使用ExcelJS實(shí)現(xiàn)Excel數(shù)據(jù)報(bào)表導(dǎo)出的完整指南
引言:ExcelJS+FileSaver如何映射到Excel操作
在開始技術(shù)細(xì)節(jié)前,讓我們建立直觀認(rèn)知 - 每個(gè)ExcelJS操作對(duì)應(yīng)Excel軟件中的什么操作:
基本對(duì)應(yīng)關(guān)系:
new Workbook()→ 打開Excel軟件addWorksheet()→ 點(diǎn)擊底部"+"新建工作表worksheet.addRow()→ 在表格中輸入一行數(shù)據(jù)cell.font→ 右鍵單元格設(shè)置字體格式worksheet.mergeCells()→ 選擇區(qū)域后點(diǎn)擊"合并單元格"
一、ExcelJS核心架構(gòu)解析 - 從文件結(jié)構(gòu)理解
1. 工作簿(Workbook)模型 - 相當(dāng)于整個(gè)Excel文件
const workbook = new ExcelJS.Workbook();
相當(dāng)于:雙擊打開一個(gè)全新的Excel文件
關(guān)鍵屬性對(duì)應(yīng):
creator→ 文件 → 信息 → 作者worksheets→ 底部工作表標(biāo)簽集合created→ 文件屬性中的創(chuàng)建時(shí)間
方法映射:
addWorksheet()→ 右鍵工作表標(biāo)簽 → 插入removeWorksheet()→ 右鍵工作表標(biāo)簽 → 刪除
2. 工作表(Worksheet)配置 - 相當(dāng)于單個(gè)工作表設(shè)置
const worksheet = workbook.addWorksheet("學(xué)生數(shù)據(jù)", {
properties: {
tabColor: { argb: 'FF00FF00' } // 綠色標(biāo)簽
}
});
相當(dāng)于:右鍵工作表標(biāo)簽 → “工作表標(biāo)簽顏色” → 選擇綠色
頁(yè)面布局對(duì)應(yīng):
worksheet.pageSetup = {
orientation: 'landscape' // 橫向
};
相當(dāng)于:頁(yè)面布局 → 紙張方向 → 橫向
二、樣式系統(tǒng)完全指南 - 精確到像素的格式控制
1. 單元格格式設(shè)置 - 等同于右鍵"設(shè)置單元格格式"
字體設(shè)置對(duì)照:
cell 是通過工作表(Worksheet)對(duì)象獲取的特定單元格引用。通俗來講:在這里cell就是你 選中工作表中的哪些部分 ,選中之后就可以 對(duì)選中的部分設(shè)置樣式 了。
cell.font = {
name: '微軟雅黑',
size: 12
};
相當(dāng)于:右鍵單元格 → 設(shè)置單元格格式 → 字體選項(xiàng)卡
邊框設(shè)置對(duì)照:
cell.border = {
top: { style: 'double' }
};
相當(dāng)于:開始 → 邊框 → 其他邊框 → 選擇上邊框線型
這里可能就是有人要問了,你的cell(單元格)是哪里來的吶?接下來告訴你真相:
2. 獲取單元格的三種主要方式

(1) 通過行列坐標(biāo)直接獲取
const cell = worksheet.getCell('B3');
// 相當(dāng)于在Excel中點(diǎn)擊B3單元格
或
const cell = worksheet.getCell(3, 2); // 行號(hào)3,列號(hào)2(即B3)
(2) 通過行對(duì)象獲取
const row = worksheet.getRow(3); // 獲取第3行 const cell = row.getCell(2); // 獲取該行第2列的單元格
(3) 添加行時(shí)直接操作
worksheet.addRow([10, '張三']).eachCell((cell, colNumber) => {
if(colNumber === 2) { // 第二列
cell.font = { name: '微軟雅黑', size: 12 };
}
});
3. 條件格式 - 對(duì)應(yīng)Excel的條件格式功能
worksheet.addConditionalFormatting({
ref: 'A1:A10',
rules: [{
type: 'cellIs',
operator: 'greaterThan',
formulae: [100],
style: { fill: { type: 'solid', fgColor: { argb: 'FFFF0000' } } }
}]
});
相當(dāng)于:開始 → 條件格式 → 突出顯示單元格規(guī)則 → 大于
三、大數(shù)據(jù)處理方案 - 對(duì)應(yīng)Excel的性能優(yōu)化
1. 流式寫入 - 類似Excel的"分頁(yè)預(yù)覽"模式
for(let i = 0; i < 100000; i++) {
worksheet.addRow([i, `Name${i}`]).commit();
}
相當(dāng)于:
- 先設(shè)置Excel選項(xiàng) → 高級(jí) → 禁用自動(dòng)計(jì)算
- 批量輸入數(shù)據(jù)后,手動(dòng)按F9重新計(jì)算
2. 性能對(duì)比 - 不同操作方式的資源消耗
| 操作方式 | Excel對(duì)應(yīng)操作 | 10萬行耗時(shí) |
|---|---|---|
| 常規(guī)寫入 | 直接輸入所有數(shù)據(jù) | 內(nèi)存溢出 |
| 流式寫入 | 啟用"手動(dòng)計(jì)算"模式 | 6.5秒 |
| 分Sheet存儲(chǔ) | 將數(shù)據(jù)分散到多個(gè)工作表 | 4.8秒 |
四、企業(yè)級(jí)報(bào)表實(shí)戰(zhàn) - 復(fù)雜報(bào)表的代碼實(shí)現(xiàn)
1. 復(fù)雜表頭 - 對(duì)應(yīng)Excel的合并單元格操作
worksheet.mergeCells('A1:D1');
相當(dāng)于:選中A1:D1區(qū)域 → 開始 → 合并后居中
斜線表頭實(shí)現(xiàn):
cell.border = {
diagonal: { up: true }
};
相當(dāng)于:右鍵單元格 → 設(shè)置單元格格式 → 邊框 → 斜線
2. 數(shù)據(jù)驗(yàn)證 - 對(duì)應(yīng)Excel的數(shù)據(jù)驗(yàn)證功能
worksheet.dataValidation.add('B2:B100', {
type: 'list',
formulae: ['"男,女"']
});
相當(dāng)于:數(shù)據(jù) → 數(shù)據(jù)驗(yàn)證 → 允許"序列" → 輸入"男,女"
3. 公式計(jì)算 - 對(duì)應(yīng)Excel的公式輸入
cell.value = {
formula: 'SUM(B2:C2)',
result: 150
};
相當(dāng)于:在單元格輸入"=SUM(B2:C2)" → 按Enter顯示計(jì)算結(jié)果
五、擴(kuò)展生態(tài)系統(tǒng) - 跨平臺(tái)導(dǎo)出方案
1. 前端導(dǎo)出 - 相當(dāng)于"另存為"操作
saveAs(new Blob([buffer]), 'report.xlsx');
相當(dāng)于:文件 → 另存為 → 選擇保存位置
2. 服務(wù)端導(dǎo)出 - 類似Web版Excel的導(dǎo)出
res.setHeader('Content-Type', 'application/vnd.ms-excel');
相當(dāng)于:SharePoint/OneDrive中的"下載"功能
結(jié)語(yǔ):構(gòu)建專業(yè)報(bào)表的工作流
標(biāo)準(zhǔn)開發(fā)流程:
- 在Excel中設(shè)計(jì)好報(bào)表模板(可視化操作)
- 記錄每個(gè)操作步驟對(duì)應(yīng)的ExcelJS API
- 將可視化操作轉(zhuǎn)化為代碼實(shí)現(xiàn)
調(diào)試技巧:
- 使用
console.log(worksheet)查看工作表結(jié)構(gòu) - 分階段導(dǎo)出檢查(先結(jié)構(gòu)后樣式)
- 在Excel中驗(yàn)證生成的公式和格式
通過這種可視化操作與代碼的精確對(duì)應(yīng),開發(fā)者可以更直觀地理解ExcelJS的各個(gè)API用途,從而構(gòu)建出真正符合業(yè)務(wù)需求的專業(yè)報(bào)表系統(tǒng)。
ExcelJS實(shí)戰(zhàn)演練:學(xué)生報(bào)名信息導(dǎo)出系統(tǒng)開發(fā)
1. 數(shù)據(jù)準(zhǔn)備階段
const transformedData = response.data.list.map((item, index) => ({
序號(hào): index + 1,
學(xué)生姓名: item.name,
性別: item.gender === "male" ? "男" : "女", // 數(shù)據(jù)字典轉(zhuǎn)換
// ...其他字段
錄取時(shí)間: item.admission_time
? dayjs(item.admission_time).format("YYYY-MM-DD HH:mm:ss")
: "--" // 處理空值
}));
關(guān)鍵點(diǎn):
dayjs處理日期格式(對(duì)應(yīng)Excel單元格格式設(shè)置)- 空值顯示為
--(符合企業(yè)報(bào)表規(guī)范) - 添加序號(hào)列(提升數(shù)據(jù)可讀性)
2. 工作簿初始化
const workbook = new ExcelJS.Workbook();
const worksheet = workbook.addWorksheet("學(xué)生報(bào)名信息");
對(duì)應(yīng)Excel操作:
新建Excel文件 → 右鍵工作表標(biāo)簽重命名
3. 主標(biāo)題設(shè)計(jì)
// 合并單元格
worksheet.mergeCells("A1:N1");
// 設(shè)置標(biāo)題內(nèi)容
const titleCell = worksheet.getCell("A1");
titleCell.value = `學(xué)生報(bào)名信息(${dateRange})`;
// 設(shè)置樣式
titleCell.font = {
name: "宋體", // 對(duì)應(yīng)Excel字體下拉框
size: 16, // 字號(hào)設(shè)置
bold: true // 加粗按鈕
};
titleCell.alignment = {
horizontal: "center" // 對(duì)應(yīng)Excel居中按鈕
};
4. 表頭實(shí)現(xiàn)
const headers = ["序號(hào)", "學(xué)生姓名", ...];
const headerRow = worksheet.addRow(headers);
// 樣式設(shè)置
headerRow.eachCell(cell => {
cell.border = {
top: { style: "thin" }, // 對(duì)應(yīng)Excel邊框工具欄
// ...其他邊框
};
cell.fill = {
type: "pattern",
pattern: "solid", // 對(duì)應(yīng)Excel油漆桶工具
fgColor: { argb: "FFD9D9D9" }
};
});
專業(yè)技巧:
eachCell方法批量設(shè)置樣式(避免重復(fù)代碼)- ARGB顏色值對(duì)應(yīng)Excel顏色選擇器
5. 數(shù)據(jù)行處理
transformedData.forEach(item => {
const row = worksheet.addRow(Object.values(item));
row.eachCell((cell, colNumber) => {
// 第六列(家庭住址)左對(duì)齊,其他居中
cell.alignment = {
horizontal: colNumber === 6 ? "left" : "center"
};
// 斑馬線效果
if(row.number % 2 === 0) {
cell.fill = {
type: "pattern",
fgColor: { argb: "FFF9F9F9" }
};
}
});
});
性能優(yōu)化:
- 只在循環(huán)內(nèi)處理必要樣式
- 使用行號(hào)(
row.number)實(shí)現(xiàn)隔行變色
6. 列寬自適應(yīng)
worksheet.columns = [
{ width: 6 }, // 序號(hào)列
{ width: 10 }, // 姓名列
// ...其他列
{ width: 30 } // 地址列(最寬)
];
設(shè)計(jì)原則:
- 身份證列固定19字符(符合18位身份證要求)
- 文本型字段適當(dāng)加寬(避免顯示####)
7. 文件導(dǎo)出
const buffer = await workbook.xlsx.writeBuffer();
const blob = new Blob([buffer], {
type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
});
saveAs(blob, `學(xué)生報(bào)名信息_${dateRange}.xlsx`);
關(guān)鍵參數(shù):
- MIME類型必須正確(否則文件損壞)
- 動(dòng)態(tài)文件名包含日期范圍
調(diào)試技巧
分階段導(dǎo)出檢查:
開發(fā)時(shí)可先注釋掉部分樣式代碼
逐步添加:先結(jié)構(gòu) → 基礎(chǔ)樣式 → 高級(jí)效果
實(shí)時(shí)查看單元格地址:
console.log(`當(dāng)前處理單元格:${cell.address}`);
樣式覆蓋檢查:
// 查看最終應(yīng)用的樣式 console.log(cell.style);
企業(yè)級(jí)增強(qiáng)建議
增加水印效果:
worksheet.background = {
imageId: 'watermark',
type: 'picture'
};
添加凍結(jié)窗格:
worksheet.views = [{
state: 'frozen',
ySplit: 2 // 凍結(jié)前兩行(標(biāo)題+表頭)
}];
數(shù)據(jù)驗(yàn)證(如性別列):
worksheet.dataValidation.add('C3:C100', {
type: 'list',
formulae: ['"男,女"']
});
(cell.style);
增加水印效果
worksheet.background = {
imageId: 'watermark',
type: 'picture'
};
添加凍結(jié)窗格:
worksheet.views = [{
state: 'frozen',
ySplit: 2 // 凍結(jié)前兩行(標(biāo)題+表頭)
}];
數(shù)據(jù)驗(yàn)證(如性別列):
worksheet.dataValidation.add('C3:C100', {
type: 'list',
formulae: ['"男,女"']
});
通過這樣逐步拆解,您可以看到每個(gè)代碼塊都對(duì)應(yīng)著具體的Excel操作,就像在GUI界面中手動(dòng)操作一樣直觀,但通過代碼實(shí)現(xiàn)了批量和精準(zhǔn)控制。
到此這篇關(guān)于使用ExcelJS實(shí)現(xiàn)Excel數(shù)據(jù)報(bào)表導(dǎo)出的完整指南的文章就介紹到這了,更多相關(guān)ExcelJS導(dǎo)出Excel內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
基于vue3+TypeScript實(shí)現(xiàn)一個(gè)簡(jiǎn)易的Calendar組件
最近在學(xué)習(xí) react,在學(xué)習(xí)到使用 react 開發(fā) Calendar 組件的時(shí)候,突然聯(lián)想到使用 vue 進(jìn)行 Calendar 功能的實(shí)現(xiàn),因?yàn)槟壳笆褂玫募夹g(shù)棧是 vue,剛好可以加深下對(duì) vue3 和 ts 的使用印象,所以本文給大家介紹了基于vue3+TypeScript實(shí)現(xiàn)一個(gè)簡(jiǎn)易的Calendar組件2024-05-05
Vue+Element UI實(shí)現(xiàn)概要小彈窗的全過程
彈窗效果是我們?nèi)粘i_發(fā)中經(jīng)常遇到的一個(gè)功能,下面這篇文章主要給大家介紹了關(guān)于Vue+Element UI實(shí)現(xiàn)概要小彈窗的相關(guān)資料,需要的朋友可以參考下2021-05-05
vue添加錨點(diǎn),實(shí)現(xiàn)滾動(dòng)頁(yè)面時(shí)錨點(diǎn)添加相應(yīng)的class操作
這篇文章主要介紹了vue添加錨點(diǎn),實(shí)現(xiàn)滾動(dòng)頁(yè)面時(shí)錨點(diǎn)添加相應(yīng)的class操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-08-08
Vue使用localStorage存儲(chǔ)數(shù)據(jù)的方法
這篇文章主要為大家詳細(xì)介紹了Vue使用localStorage存儲(chǔ)數(shù)據(jù)的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-05-05
關(guān)于element中對(duì)el-input 自定義驗(yàn)證規(guī)則
這篇文章主要介紹了關(guān)于element中對(duì)el-input 自定義驗(yàn)證規(guī)則,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-08-08
VUE使用DXFParser組件解析dxf文件生成圖片的操作代碼
這篇文章主要介紹了VUE使用DXFParser組件解析dxf文件生成圖片的操作代碼,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-09-09

