在数据量不太大,或者开发周期比较急迫的情况下,可以把导出excel功能放到前端实现。
这里笔者结合实际开发的经验,由于我司开发技术选型为React,最终选择
js-export-excel (1.1.4) 和 xlsx (0.18.5)
分别进行介绍如何实现前端导出excel功能。
{#_label1}
前置数据模拟以及导出预期结果 {#heading-1}
{#_lab2_1_0}
mock导出的数据 {#heading-2}
const dataTable = [
{index: "1", name: "niko", age: "18", birth: "Mon Dec 11 10:08:15 CST 2023"},
{index: "1", name: "vivi", age: "16", birth: "Sun Dec 11 10:49:18 CST 2023"},
]
预期导出效果 {#heading-3}
只需要序号,姓名和年龄字段,且工作表名为个人信息表
js-export-excel {#heading-4}
import ExportJsonExcel from 'js-export-excel';
const jsExportExcelHandle = (dataTable = []) => {
const option = [];
option.fileName = "个人信息文件";
const sheetData = dataTable; // 有需要映射的话需要先映射
const sheetFilter = ["index", "name", "age"];
const sheetHeader = ["序号", "姓名", "年龄"];
option.datas = [
{
sheetData,
sheetName: "个人信息表",
sheetFilter,
sheetHeader,
columnWidth: new Array(sheethaeader.length).fill(10); // 列宽
}
];
const toExcel = new ExportJsonExcel(option);
toExcel.saveExcel()
}
xlsx {#heading-5}
import { utils, writeFile } from 'xlsx';
const xlsxHandle = (dataTable = []) => {
// 表头映射为中文
const headerMap = {
index: "序号",
name: "姓名",
age: "年龄",
},
// 先过滤出需要的属性
const headList = Object.keys(headerMap);
// 返回新的对象数组
const _dataTable = dataTable.map(item => {
const filteredItem = {};
Object.keys(item).forEach(key => {
if(headList.includes(key)){
filteredItem[key] = item[key];
}
})
return filteredItem
})
// xlsx需要转为二维数组
const dataArr = _dataTable.map(item => Object.values(item));
// 将表头映射为中文(name => 姓名)
const headerTranslated = Object.keys(headerMap).map(key => header[key]);//["序号", "年龄", "姓名"]
dataArr.unshif(headerTranslated); // 插入
const workSheet = utils.aoa_to_sheet(dataArr); // 转为工作表对象
// 设置每个的单元格的列宽
workSheet["!cols"] = new Array(headList.length).fill({wch: 20}); // {!cols:(13)[{wch:20},...],A1:{v: "序号", t: "s"},...}
const workBook = utils.book_new();
utils.book_append_sheet(workBook, workSheet);
// writeFile 方法只能在 node 环境下使用。
writeFile(workBook, "个人信息文件.xlsx", {
Props: { // 作者的相关信息
title: "个人信息明细",
creator: window.User,
}
})
}
worksheet['!cols']
:存储列对象的数组,可以在这里设置列宽。
//wpx 字段表示以像素为单位,wch 字段表示以字符为单位
worksheet['!cols'] = [
{ wpx: 200 }, //设置第1列列宽为200像素
{ wch: 50 }, //设置第2列列宽为50字符
];
单元格对象中的属性
//设置A1单元格的值是序号,类型是字符串,字体颜色是FF0187FA
worksheet["A1"] = {
v: "序号",
t: "s",
s: {
font: {
color: { rgb: "FF0187FA" }
},
}
}
总结 {#heading-6}
其实js-export-excel是在xlsx的基础上二次封装的,以上是个人工作中对于第三方插件使用的一个小记录,有写错的地方还请不吝赐教
2024更新
使用xlsx转为二维数组的时候,可能导致数据和表头对应不上的问题(23行)
// 应该根据表头headerMap重新组装每一行的对象
const dataArr = _dataTable.map(item =>
Object.keys(headerMap)
.map(key => item[key])
)