Node.js讀取Excel文件并處理合并單元格
在現代的數據處理任務中,Excel 文件是一種非常常見的數據存儲格式。無論是數據分析、報表生成,還是數據遷移,Excel 文件都扮演著重要的角色。然而,處理 Excel 文件時,尤其是包含合并單元格的文件,可能會遇到一些挑戰(zhàn)。本文將介紹如何使用 Node.js 讀取 Excel 文件,并處理其中的合并單元格。

準備工作
首先,我們需要安裝一些必要的 Node.js 庫。我們將使用 xlsx 庫來讀取和解析 Excel 文件,使用 lodash 庫來處理字符串。你可以通過以下命令安裝這些庫:
npm install xlsx lodash
讀取 Excel 文件
我們首先需要讀取 Excel 文件。假設我們的文件名為 YD-TP2025-03-22.xlsx,并且它位于當前項目的根目錄下。我們可以使用 xlsx.readFile 方法來讀取文件:
const xlsx = require('xlsx');
const path = require('path');
???????const filePath = path.join(__dirname, 'YD-TP2025-03-22.xlsx');
const workbook = xlsx.readFile(filePath);
獲取工作表
接下來,我們需要獲取 Excel 文件中的特定工作表。假設我們的工作表名為 建設全流程明細,我們可以通過以下代碼獲取該工作表:
const sheetName = "建設全流程明細"; const sheet = workbook.Sheets[sheetName];
處理合并單元格
在處理 Excel 文件時,合并單元格是一個常見的挑戰(zhàn)。合并單元格的值通常只存儲在合并區(qū)域的左上角單元格中,其他單元格的值為空。為了正確處理合并單元格,我們需要獲取合并單元格的信息,并根據這些信息來獲取正確的值。
我們可以通過以下代碼獲取工作表的合并單元格信息:
const merges = sheet['!merges'] || [];
然后,我們定義一個函數 getMergedCellValue,用于獲取合并單元格的值:
function getMergedCellValue(sheet, row, col) {
for (const merge of merges) {
const { s, e } = merge; // s: 合并區(qū)域的起始位置,e: 合并區(qū)域的結束位置
if (row >= s.r && row <= e.r && col >= s.c && col <= e.c) {
return sheet[xlsx.utils.encode_cell(s)]?.v;
}
}
return sheet[xlsx.utils.encode_cell({ r: row, c: col })]?.v;
}
獲取表頭數據
假設我們的表頭數據位于第 4 行,我們可以通過以下代碼獲取表頭數據:
const headerTemplates = [];
const rowIndex = 3; // 第 4 行的索引(從 0 開始)
const range = xlsx.utils.decode_range(sheet['!ref']);
for (let col = range.s.c; col <= range.e.c; col++) {
const cellValue = getMergedCellValue(sheet, rowIndex, col);
if (cellValue) {
const address = xlsx.utils.encode_cell({ r: rowIndex, c: col }) + '';
headerTemplates.push({
address: address,
value: removeTabsAndNewlines(cellValue),
col: col + 1 // Excel 列從 1 開始計數
});
}
}
輸出表頭模板數據
最后,我們可以將獲取到的表頭數據輸出為 JSON 格式:
console.log(JSON.stringify(headerTemplates, null, 2));
[Running] node "c:\Users\xiong\WebstormProjects\backendnodejs\src\models\scripts\tempCodeRunnerFile.js"
[
{
"address": "A4",
"value": "序號",
"col": 1
},
{
"address": "B4",
"value": "區(qū)縣",
"col": 2
},
{
"address": "C4",
"value": "線下收到需求時間(以郵件為準等書面通知為準)",
"col": 3
},
{
"address": "D4",
"value": "訂單編號",
"col": 4
},
{
"address": "E4",
"value": "未進系統(tǒng)原因",
"col": 5
},
{
"address": "F4",
"value": "年份",
"col": 6
},
{
"address": "G4",
"value": "運營商",
"col": 7
},將數據轉換為結構化 JSON
接下來,我們從第 5 行(索引為 4)開始讀取數據,并將每一行數據轉換為一個對象,其中鍵為表頭字段,值為單元格內容。最后,將所有數據存儲在一個數組中
const xlsx = require('xlsx');
const path = require('path');
// 讀取 Excel 文件
const filePath = path.join(__dirname, 'YD-TP2025-03-22.xlsx');
const workbook = xlsx.readFile(filePath);
// 獲取名為 "建設全流程明細" 的工作表
const sheetName = "建設全流程明細";
const sheet = workbook.Sheets[sheetName];
// 獲取工作表的合并單元格信息
const merges = sheet['!merges'] || [];
// 定義一個函數,用于獲取合并單元格的值
function getMergedCellValue(sheet, row, col) {
for (const merge of merges) {
const { s, e } = merge;
if (row >= s.r && row <= e.r && col >= s.c && col <= e.c) {
return sheet[xlsx.utils.encode_cell(s)]?.v;
}
}
return sheet[xlsx.utils.encode_cell({ r: row, c: col })]?.v;
}
// 獲取表頭數據(第 4 行)
const headerRow = [];
const headerRowIndex = 3; // 第 4 行的索引(從 0 開始)
const range = xlsx.utils.decode_range(sheet['!ref']);
// 獲取表頭
for (let col = range.s.c; col <= range.e.c; col++) {
const cellValue = getMergedCellValue(sheet, headerRowIndex, col);
headerRow.push(cellValue || '');
}
// 將數據轉換為列表
const dataList = [];
// 從第5行開始讀取數據(索引4)
for (let row = headerRowIndex + 1; row <= range.e.r; row++) {
const rowData = {};
// 遍歷每一列
for (let col = range.s.c; col <= range.e.c; col++) {
const cellValue = getMergedCellValue(sheet, row, col);
// 使用表頭作為鍵名
rowData[headerRow[col]] = cellValue || '';
}
dataList.push(rowData);
}
// 輸出前5條數據作為示例
console.log('數據總條數:', dataList.length);
console.log('前5條數據示例:');
console.log(JSON.stringify(dataList.slice(5, 25), null, 2));
[Running] node "c:\Users\xiong\WebstormProjects\backendnodejs\src\models\scripts\excel_tolist.js"
數據總條數: 9
前5條數據示例:
[
{
"序號": 5,
"區(qū)縣": "長沙縣",
"線下收到需求時間\n(以郵件為準等書面通知為準)": 45523,
"訂單編號": "新建選址",
"未進系統(tǒng)原因": "新建選址完成后進系統(tǒng)",
"年份": "2024年",
"運營商": "移動",
"項目歸屬": "岳麓山景區(qū)",
"運營商批次": "普通5G",
"重點項目打標": "",
"需求站址名稱": "長沙岳麓岳麓山東門路口微站H-H5X",
"鐵塔站址名稱": "",
"鐵塔站址編碼": "",
"項目編碼/存量滿足": "",
"立項方式(存量滿足常規(guī)塔類/區(qū)域化塔類/非標改造)": "微站",
"運營商建設方式(新址新建、共址新建、共址改造)": "新址新建",
"鐵塔建設方式(新建、改造、存滿)": "新建",
"產品單元數": 1,
"建設類型(地面站,樓面站)": "地面站",
"建設方案\n(含所有建設工程量)": "利舊電力路燈桿,新增光電一體箱,新增支臂,外市電",
"打標": "2、地面新建",
"訂單導入時間": "",
............
總結
通過以上步驟,我們成功地使用 Node.js 讀取了 Excel 文件,并處理了其中的合并單元格。這種方法不僅適用于獲取表頭數據,還可以用于處理其他復雜的 Excel 數據。
到此這篇關于Node.js讀取Excel文件并處理合并單元格的文章就介紹到這了,更多相關Node.js讀取Excel內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Node.js + Redis Sorted Set實現任務隊列
本文給大家分享的是使用Node.js + Redis Sorted Set實現任務隊列的方法示例,非常的實用,有需要的小伙伴可以參考下2016-09-09
Node.js?使用?zlib?內置模塊進行?gzip?壓縮
這篇文章主要介紹了Node.js?使用?zlib?內置模塊進行?gzip?壓縮,nodejs為我們提供了一個zlib內置模塊,我們可以使用它其中的gzip方法來對傳遞的數據進行壓縮,從而提高數據傳遞效率,更多相關內容需要的朋友可以參考一下2022-09-09
PHP和NodeJs開發(fā)的應用如何共用Session
這篇文章主要介紹了PHP和NodeJs開發(fā)的應用如何共用Session的相關資料及思路,需要的朋友可以參考下2015-04-04

