前端复杂表格导出excel,一键导出 Antd Table 看这篇就够了(附源码)

本文详细讲解如何使用ExcelJS库从Antd Table导出带有样式的复杂Excel文件,包括设置背景色、字体样式、对齐方式、行合并和列合并。通过实例代码展示了从解析Antd Table到实现多级表头、自定义样式和多张表的导出全过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前端导出 excel 的需求很多,但市面上好用的库并不多,讲明白复杂使用场景的文章更少。

本文将以文字 + demo 源码的形式,力求讲清楚满足 99% 使用场景的终极 excel 导出方案。

如果项目中用到了 AntD,那就更简单了,因为 Table 本身已经设置好了 column 和 dataSource,只需解析 column 和 dataSource 即可快速导出 Excel。

实现功能:

  • 简单表格导出
  • 为表格添加样式(更改背景色、更换字体、字号、颜色)
  • 设置行高、列宽
  • 解析 ant-design 的 Table 直接导出excel,根据 antd 页面中设置的列宽动态计算 excel 中的列宽
  • 多级表头(行合并、列合并)
  • 一个 sheet 中放多张表,并实现每张表的列宽不同

源码地址:https://github.com/cachecats/excel-export-demo

第二篇文章:js 批量导出 excel 为zip压缩包, 对导出方法进行了封装,还实现了使用 exceljsfile-saverjszip实现下载包含多层级文件夹、多个 excel、每个 excel 支持多个 sheet 的 zip 压缩包。

一、技术选型

xlsx

呼声最高的是 xlsx,又叫 SheetJS,也是下载量最高和 star最多的库。试用了一下很强大,但是!默认不支持改变样式,想要支持改变样式,需要使用它的收费版本。

本着勤俭节约的原则,很多人使用了另一个第三方库:xlsx-style,但是使用起来极其复杂,还需要改 node_modules 源码,这个库最后更新时间也定格在了 6年前。还有一些其他的第三方样式拓展库,质量参差不齐。

使用成本和后期的维护成本很高,不得不放弃。

ExcelJS

ExcelJS 周下载量 450k,github star 9k,并且拥有中文文档,对国内开发者很友好。虽然文档是以README 的形式,可读性不太好,但重在内容,常用的功能基本都有覆盖。

最近更新时间是6个月内,试用了一下,集成很简单,再加之文档丰富,就选它了。

安装:

npm install exceljs

下载到本地还需要另一个库:file-saver

npm install file-saver

二、基本概念

先了解下基本概念,更详细的介绍参考官方文档:https://github.com/exceljs/exceljs/blob/HEAD/README_zh.md

workbook

workbook:工作簿,可以理解为整个 excel 表格。

通过 const workbook = new ExcelJS.Workbook() 创建工作簿,还可以设置工作簿的属性:

workbook.creator = 'Me';
workbook.lastModifiedBy = 'Her';
workbook.created = new Date(1985, 8, 30);
workbook.modified = new Date();
workbook.lastPrinted = new Date(2016, 9, 27);

worksheet

工作表,即 Excel 表格中的 sheet 页。

通过 const sheet = workbook.addWorksheet('My Sheet')创建工作表,每个 workbook 可添加多个 worksheet。

使用 addWorksheet 函数的第二个参数来指定工作表的选项。

// 创建带有红色标签颜色的工作表
const sheet = workbook.addWorksheet('My Sheet', {properties:{tabColor:{argb:'FFC0000'}}});

// 创建一个隐藏了网格线的工作表
const sheet = workbook.addWorksheet('My Sheet', {views: [{showGridLines: false}]});

// 创建一个第一行和列冻结的工作表
const sheet = workbook.addWorksheet('My Sheet', {views:[{xSplit: 1, ySplit:1}]});

// 使用A4设置的页面设置设置创建新工作表 - 横向
const worksheet =  workbook.addWorksheet('My Sheet', {
  pageSetup:{paperSize: 9, orientation:'landscape'}
});

// 创建一个具有页眉页脚的工作表
const sheet = workbook.addWorksheet('My Sheet', {
  headerFooter:{firstHeader: "Hello Exceljs", firstFooter: "Hello World"}
});

// 创建一个冻结了第一行和第一列的工作表
const sheet = workbook.addWorksheet('My Sheet', {views:[{state: 'frozen', xSplit: 1, ySplit:1}]});

columns

列,通过 worksheet.columns可设置表头。

// 添加列标题并定义列键和宽度
// 注意:这些列结构仅是构建工作簿的方便之处,除了列宽之外,它们不会完全保留。
worksheet.columns = [
  { header: 'Id', key: 'id', width: 10 },
  { header: 'Name', key: 'name', width: 32 },
  { header: 'D.O.B.', key: 'DOB', width: 10, outlineLevel: 1 }
];

// 通过键,字母和基于1的列号访问单个列
const idCol = worksheet.getColumn('id');
const nameCol = worksheet.getColumn('B');
const dobCol = worksheet.getColumn(3);

// 设置列属性

// 注意:将覆盖 C1 单元格值
dobCol.header = 'Date of Birth';

// 注意:这将覆盖 C1:C2 单元格值
dobCol.header = ['Date of Birth', 'A.K.A. D.O.B.'];

// 从现在开始,此列将以 “dob” 而不是 “DOB” 建立索引
dobCol.key = 'dob';

dobCol.width = 15;

// 如果需要,隐藏列
dobCol.hidden = true;

还可对列进行各种操作。

// 遍历此列中的所有当前单元格
dobCol.eachCell(function(cell, rowNumber) {
  // ...
});

// 遍历此列中的所有当前单元格,包括空单元格
dobCol.eachCell({ includeEmpty: true }, function(cell, rowNumber) {
  // ...
});

// 添加一列新值
worksheet.getColumn(6).values = [1,2,3,4,5];

// 添加稀疏列值
worksheet.getColumn(7).values = [,,2,3,,5,,7,,,,11];

// 剪切一列或多列(右边的列向左移动)
// 如果定义了列属性,则会相应地对其进行切割或移动
// 已知问题:如果拼接导致任何合并的单元格移动,结果可能是不可预测的
worksheet.spliceColumns(3,2);

// 删除一列,再插入两列。
// 注意:第4列及以上的列将右移1列。
// 另外:如果工作表中的行数多于列插入项中的值,则行将仍然被插入,就好像值存在一样。
const newCol3Values = [1,2,3,4,5];
const newCol4Values = ['one', 'two', 'three', 'four', 'five'];
worksheet.spliceColumns(3, 1, newCol3Values, newCol4Values);

row

行,可以添加一行或者同时添加多行数据,是使用最频繁的属性。

// 通过 json 添加一行数据,需要先设置 columns
worksheet.addRow({id: 1, name: 'John Doe', dob: new Date(1970,1,1)});
worksheet.addRow({id: 2, name: 'Jane Doe', dob: new Date(1965,1,7)});
// 通过数组添加一行数据
worksheet.addRow([3, 'Sam', new Date()]);

// 同时添加多行数据
worksheet.addRows(list);

// 遍历工作表中具有值的所有行
worksheet.eachRow(function(row, rowNumber) {
  console.log('Row ' + rowNumber + ' = ' + JSON.stringify(row.values));
});

// 遍历工作表中的所有行(包括空行)
worksheet.eachRow({ includeEmpty: true }, function(row, rowNumber) {
  console.log('Row ' + rowNumber + ' = ' + JSON.stringify(row.values));
});

// 连续遍历所有非空单元格
row.eachCell(function(cell, colNumber) {
  console.log('Cell ' + colNumber + ' = ' + cell.value);
});

// 遍历一行中的所有单元格(包括空单元格)
row.eachCell({ includeEmpty: true }, function(cell, colNumber) {
  console.log('Cell ' + colNumber + ' = ' + cell.value);
});

三、简单表格导出

本文所有示例都使用 React + AntD。

先看效果,我们用 AntD 的 Table 写个简单的表格页面,并设置不同的列宽:

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值