在现代 Web 应用中,处理 Excel 文件已成为常见需求——无论是生成导入模板、导出报表,还是批量数据处理。相比传统的 CSV,Excel 格式更适用于复杂结构、格式控制、多 Sheet、多类型等场景。
本文将深入介绍 ExcelJS 的核心能力、典型场景与高级用法,帮助你构建稳定且高扩展性的表格处理模块。
一、ExcelJS 简介
ExcelJS 是一款基于 Node.js 的 Excel 读写库,支持:
创建和修改
.xlsx
文件;支持格式化单元格(字体、颜色、对齐等);
支持数据验证、下拉框、合并单元格;
支持读取已有 Excel 文件;
支持流式写入(适合大文件处理);
不依赖 Excel 安装环境,跨平台运行。
安装命令:
npm install exceljs
二、创建 Excel 文件(基础用法)
创建工作簿和工作表
const ExcelJS = require('exceljs');
const workbook = new ExcelJS.Workbook();
const worksheet = workbook.addWorksheet('产品列表');
设置列和添加数据
worksheet.columns = [
{ header: '商品编码', key: 'code', width: 15 },
{ header: '名称', key: 'name', width: 25 },
{ header: '价格', key: 'price', width: 10 },
{ header: '库存', key: 'stock', width: 10 }
];
worksheet.addRow({ code: 'A001', name: 'T恤', price: 199, stock: 20 });
worksheet.addRow({ code: 'A002', name: '牛仔裤', price: 299, stock: 15 });
设置样式
worksheet.getRow(1).font = { bold: true, color: { argb: 'FF0000FF' } }; // 表头加粗蓝色
保存文件
await workbook.xlsx.writeFile('商品列表.xlsx');
三、读取 Excel 文件
const workbook = new ExcelJS.Workbook();
await workbook.xlsx.readFile('商品列表.xlsx');
const worksheet = workbook.getWorksheet('产品列表');
worksheet.eachRow((row, rowNumber) => {
console.log(`第${rowNumber}行:`, row.values);
});
四、常见使用场景与示例
1. ✅ 生成导入模板(字段格式控制)
worksheet.columns = [
{ header: '姓名', key: 'name', width: 20 },
{ header: '身份证号', key: 'idCard', width: 25 },
{ header: '手机号', key: 'mobile', width: 20 }
];
// 设置所有列为文本格式(避免科学计数法)
worksheet.columns.forEach(col => {
col.numFmt = '@';
});
2. ✅ 设置下拉选择(数据验证)
worksheet.getCell('D2').dataValidation = {
type: 'list',
allowBlank: true,
formulae: ['"男,女"']
};
3. ✅ 合并单元格 + 设置样式
worksheet.mergeCells('A1:D1');
worksheet.getCell('A1').value = '销售报表';
worksheet.getCell('A1').alignment = { horizontal: 'center' };
worksheet.getCell('A1').font = { size: 14, bold: true };
4. ✅ 冻结窗格
worksheet.views = [{ state: 'frozen', ySplit: 1 }];
5. ✅ 条件格式(模拟)
ExcelJS 不原生支持条件格式,但可通过遍历逻辑模拟颜色高亮:
worksheet.eachRow((row, index) => {
if (index > 1 && row.getCell(3).value > 500) {
row.getCell(3).fill = {
type: 'pattern',
pattern: 'solid',
fgColor: { argb: 'FFFFAAAA' }
};
}
});
五、处理大数据量:流式写入
ExcelJS 支持通过 workbook.xlsx.writeBuffer()
或 write
流式方式导出大型 Excel 文件。
const workbook = new ExcelJS.stream.xlsx.WorkbookWriter({
filename: 'big-file.xlsx'
});
const worksheet = workbook.addWorksheet('数据');
for (let i = 0; i < 100000; i++) {
worksheet.addRow({ id: i, value: `数据-${i}` }).commit();
}
await workbook.commit();
六、最佳实践与注意事项
项目 | 建议说明 |
---|---|
数据格式 | 用 col.numFmt = '@' 显式设为文本,防止 Excel 自动格式化 |
性能 | 使用流式写入处理 10 万行以上数据,避免内存爆炸 |
表头样式统一 | 用统一方法封装表头样式设置(加粗、居中、背景色) |
模板导入校验 | 提供模板下载 + 导入校验(字段格式、必填、枚举值) |
多 Sheet 支持 | addWorksheet() 添加多个 sheet,适合多表结构导出 |
中文兼容性 | 字体建议使用 微软雅黑 保证字体可识别 |
七、典型行业应用场景
场景 | 用法建议 |
---|---|
电商商品导入导出 | 支持多规格 SKU、分类映射、价格与库存字段 |
企业数据报表 | 合并单元格、分组、图表生成(可结合其他工具) |
人事薪资管理 | 导入模板校验 + 导出格式美化,支持下拉选择 |
政府数据上报 | 数据精度要求高,建议所有字段都设为文本型 |
保险/医疗行业记录导入 | 精度控制严谨,避免日期和身份证自动格式化 |
八、替代方案对比
库名 | 语言 | 读取 | 写入 | 格式控制 | 适合大文件 | 备注 |
---|---|---|---|---|---|---|
ExcelJS | Node.js | ✅ | ✅ | ✅ | ✅(支持流) | 活跃维护,适合服务端生成 |
SheetJS (xlsx) | JS | ✅ | ✅ | 较弱 | ❌ | 更适合浏览器端解析 |
Apache POI | Java | ✅ | ✅ | ✅ | ✅ | Java 社区主流方案 |
pandas + openpyxl | Python | ✅ | ✅ | ✅ | 一般 | 适合数据分析导出 |
结语:架构师视角的 ExcelJS 模块设计建议
为提高复用性与工程可维护性,建议对 ExcelJS 使用封装如下模块结构:
excel/
├── ExcelTemplateService.js // 模板生成(字段+样式+示例)
├── ExcelImportService.js // 读取校验逻辑
├── ExcelExportService.js // 导出逻辑封装
├── ExcelUtils.js // 公共样式、下拉、格式化工具
结合 Web 框架(如 NestJS/Express),可构建企业级数据处理平台的一部分。