场景
在工作中,当后端返回的是json数据时,此时需要前端自己将数据在浏览器导出成Excel文件并保存到本地时,我们可以使用Excel.js库创建excel文件,然后再使用 file-saver库将 Excel 文件保存到用户的本地计算机
介绍
1.Excel.js
Excel.js 是一个 JavaScript 库,用于在浏览器或 Node.js 环境中操作 Excel 文件。它提供了丰富的功能,可以创建、读取、修改和保存 Excel 文件。Excel.js 不是一个插件,而是一个独立的库,你可以使用它与其他 JavaScript 应用程序集成。要使用 Excel.js,你需要通过 npm 或 yarn 安装它,然后在你的代码中引入它。
2. file-saver
file-saver 是一个 JavaScript 库,用于在浏览器中保存文件。它提供了一个方便的接口,使你能够将数据保存到用户的本地计算机,而无需依赖服务器端的下载。file-saver 支持将文件保存为 Blob 对象或者直接将 Data URL 保存为文件。
一、如何使用Excel.js和 file-saver
1. 安装与引入
通过npm安装:
npm install exceljs
npm install file-saver
通过yarn安装:
yarn add exceljs
npm install file-saver
导入:
import * as ExcelJS from 'exceljs';
import { saveAs } from 'file-saver';
2. 使用创建Excel
创建工作簿,设置列信息。header表示第一行的行标题,key表示每一列对应的数据的名字,width表示每一列的宽度
const workbook = new ExcelJS.Workbook(); // 创建一个excel工作薄
const worksheet = workbook.addWorksheet('Sheet1'); // 创建一个工作表
worksheet.columns = [ // 设置工作表的列信息
{ header: '资产编码', key: 'assetCode', width: 32 },
{ header: '资产名称', key: 'assetName', width: 10 },
{ header: '使用部门', key: 'usingDepart', width: 32 },
{ header: '原值', key: 'originalValue', width: 32 },
{ header: '资产类别', key: 'categoryName', width: 32 },
{ header: '残值率(%)', key: 'salvageRate', width: 32 },
{ header: '残值', key: 'salvageValue', width: 32 },
{ header: '月初累计折旧', key: 'accumulationValue', width: 32 },
{ header: '本月折旧', key: 'monthValue', width: 32 },
{ header: '月末累计折旧', key: 'endValue', width: 32 },
{ header: '资产净值', key: 'netValue', width: 32 }
]
设置标题行的样式
// 设置标题行的边框样式
const row1 = worksheet.getRow(1);
row1.height = 14.4;
worksheet.getRow(1).eachCell((cell) => {
cell.border = {
top: { style: 'thin' },
left: { style: 'thin' },
bottom: { style: 'thin' },
right: { style: 'thin' }
};
cell.font = {
name: "黑体",
bold: true,
color: {
// 注意:在 exceljs 中所有的的颜色值均为 argb 格式,且不带 # 符号
argb: "ffffff",
},
}
cell.fill = {
type: "pattern",
pattern: "solid",
fgColor: {
argb: "808080",
},
}
});
// 设置标题行的居中对齐
worksheet.getRow(1).eachCell((cell) => {
cell.alignment = { horizontal: 'center', vertical: 'middle' };
});
创建一个变量接收要转换成Excel表的数据,我此处是使用map将一个数组对象中的对象都取出来转换成列信息里面对应的key的名字,然后将数据添加到工作表中
const data = this.tableDate.map(({
assetCode,
assetName,
usingDepart,
originalValue,
categoryName,
salvageRate,
salvageValue,
accumulationValue,
monthValue,
endValue,
netValue }
) => ({
assetCode,
assetName,
usingDepart,
originalValue,
categoryName,
salvageRate,
salvageValue,
accumulationValue,
monthValue,
endValue,
netValue }))
// 将数据添加到工作表中
worksheet.addRows(data);
接下来就是给单元格设置样式,着重要注意边框的设置,要处理当数据为null时的情况。处理方法是可以获取到工作表的最大行数和列数然后使用for循环遍历单元格进行判断后单独设置自定义样式于空单元格。
// 设置单元格边框样式
const borderStyle = {
style: 'thin',
color: { argb: '000000' }
};
// 获取工作表的最大行数和列数
const maxRow = worksheet.rowCount;
const maxCol = worksheet.columnCount;
// 遍历单元格
for (let row = 1; row <= maxRow; row++) {
for (let col = 1; col <= maxCol; col++) {
const cell = worksheet.getCell(row, col);
if (cell.value === null || cell.value === undefined || cell.value === "") {
// 应用自定义样式于空单元格
cell.border = {
top: borderStyle,
left: borderStyle,
bottom: borderStyle,
right: borderStyle
};
} else {
// 设置非空单元格的边框样式
cell.border = {
top: borderStyle,
left: borderStyle,
bottom: borderStyle,
right: borderStyle
};
}
// 设置居中对齐和自动换行
cell.alignment = {
horizontal: 'center',
vertical: 'middle',
wrapText: true
};
}
}
最后就可以使用file-saver中的saveAs将Excel文件导出保存了。使用 workbook.xlsx.writeBuffer() 方法将 Excel 工作簿(Workbook)对象的内容写入到一个 ArrayBuffer 缓冲区中,并返回一个 Promise。接着,它创建了一个 Blob 对象,使用该 ArrayBuffer 作为数据源,并设置 MIME 类型为 application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,表示这是一个 Excel 文档的 MIME 类型。最后,通过调用 saveAs 函数,将该 Blob 对象保存为一个带有时间戳的 Excel 文件。
const buffer = await workbook.xlsx.writeBuffer()
const blob = new Blob([buffer], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
saveAs(blob, `basic_${new Date().getTime()}.xlsx`)