📊 Vue 前端表格與 Excel 匯出合併儲存格完整教學(含範例程式碼)

 

🔍 前言

在專案開發中,我們常需要在網頁上呈現複雜的表格,並支援 Excel 匯出
但有一個棘手的需求:不同條件下需要自動合併儲存格。例如:

  • APS_PLAN_NO 不同 → 絕對不能合併

  • APS_PLAN_NO 相同 → 依照其他欄位內容是否一致來決定是否合併

本文將帶你一步一步實作,從 Vue 前端表格的合併邏輯,到 Excel 匯出時保持同樣效果。


🖥️ Vue 表格合併邏輯

我們的需求規則如下:

  1. APS_PLAN_NO 是最高優先條件

    • 若 APS_PLAN_NO 不同 → 全欄位都不能合併。

  2. APS_PLAN_NO 相同時

    • 逐一檢查欄位值,若連續相同則進行合併。

    • 若不相同則不合併。

Vue rowSpans 計算程式碼

以下是核心程式碼,放在 rowSpans 計算屬性:

const rowSpans = computed(() => { const rows = filteredData.value; const spans = rows.map(() => { const obj = {}; tableHeaders.value.forEach(key => obj[key] = 0); return obj; }); let start = 0; while (start < rows.length) { let end = start + 1; while (end < rows.length && rows[end]['APS_PLAN_NO'] === rows[start]['APS_PLAN_NO']) { end++; } tableHeaders.value.forEach(key => { let i = start; while (i < end) { let j = i + 1; while (j < end && rows[j][key] === rows[i][key]) j++; const span = j - i; spans[i][key] = span > 1 ? span : 1; i = j; } }); start = end; } return spans; });

這段程式的效果就是:
先按照 APS_PLAN_NO 切分區段
區段內再逐欄檢查是否需要合併


📑 Excel 匯出保持合併

除了在前端表格上呈現,很多公司還會要求「Excel 匯出」也要有相同的合併效果。

這裡我們使用 SheetJS (XLSX),搭配自訂的 merges 設定來實現。

Excel 匯出程式碼

以下是完整的 exportToExcel 實作:

function exportToExcel() { if (!mappedTableData.value.length) { alert('沒有資料可匯出') return } const dataToExport = filteredData.value const groupRow = tableHeaders.value.map((key, idx) => { if (idx < 9) return uppercaseMapping[key] || key if (idx < 11) return '考題結論' if (idx < 16) return '評估明細_TFT' if (idx < 21) return '評估明細_LCM' return '評估明細_Material' }) const subHeaderRow = tableHeaders.value.map((key) => uppercaseMapping[key] || key) const bodyRows = dataToExport.map((row) => tableHeaders.value.map((key) => row[key] ?? '')) const merges = [] // 表頭合併設定 for (let c = 0; c < 9; c++) merges.push({ s: { r: 0, c }, e: { r: 1, c } }) merges.push({ s: { r: 0, c: 9 }, e: { r: 0, c: 10 } }) merges.push({ s: { r: 0, c: 11 }, e: { r: 0, c: 15 } }) merges.push({ s: { r: 0, c: 16 }, e: { r: 0, c: 20 } }) merges.push({ s: { r: 0, c: 21 }, e: { r: 0, c: 25 } }) // 依 APS_PLAN_NO 分段 → 再逐欄位合併 let start = 0 while (start < bodyRows.length) { let end = start + 1 while (end < bodyRows.length && bodyRows[end][tableHeaders.value.indexOf('APS_PLAN_NO')] === bodyRows[start][tableHeaders.value.indexOf('APS_PLAN_NO')]) { end++ } for (let col = 0; col < tableHeaders.value.length; col++) { let i = start while (i < end) { let j = i + 1 while (j < end && bodyRows[j][col] === bodyRows[i][col]) j++ if (j - i > 1) { merges.push({ s: { r: i + 2, c: col }, e: { r: j - 1 + 2, c: col } }) } i = j } } start = end } const ws = XLSX.utils.aoa_to_sheet([groupRow, subHeaderRow, ...bodyRows]) ws['!merges'] = merges const wb = XLSX.utils.book_new() XLSX.utils.book_append_sheet(wb, ws, 'APS 排程結果') const buf = XLSX.write(wb, { bookType: 'xlsx', type: 'array' }) saveAs(new Blob([buf], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' }), `APS排程結果_${selectedVersion.value}.xlsx`) }

📌 實際應用場景

這樣的需求常見於:

  • 製造業 APS 排程系統(如 TFT-LCD、半導體業)

  • 財務/會計報表(不同部門資料合併展示)

  • 行銷數據分析(分群數據導出 Excel)

透過這套邏輯,你可以確保 網頁與 Excel 完全一致,避免人工整理的時間成本。


✅ 結論

本文介紹了如何在 Vue 前端表格Excel 匯出中,實現 APS_PLAN_NO 分段 + 欄位逐一合併 的邏輯。
這個技巧特別適合需要 專業報表、跨系統數據整合 的專案。

若你正在開發類似的系統,可以直接複製程式碼,並依專案需求微調。

留言

這個網誌中的熱門文章

🔍Vue.js 專案錯誤排查:解決 numericFields is not defined 與合併儲存格邏輯最佳化

🔎EF Core 連 Oracle 出現 ORA-00600 [kpp_concatq:2] 的完整排錯指南(含 EF Core ToString/CultureInfo 錯誤)

🛠【ASP.NET Core + Oracle】解決 ORA-00904 "FALSE": 無效的 ID 錯誤與資料欄位動態插入顯示問題