写在前面
无论是做项目还是自己学习过程中,我们可能会遇到导出数据的需求,比如导出数据到Excel文件。
为了方便大家的学习和开发,这里介绍一种导出数据到Excel文件的方法。
方法简介
我在这里使用 exceljs 包来导出数据,如果你有兴趣,可以阅读一下他们的文档:
如果你想直接看Demo和源码,可以直接访问我在codesandbox部署的代码:codesandbox.io/s/react-exp…
导出后的数据如下:
方法代码详解
1. 引入依赖包和需要导出的数据
首先我们需要引入依赖包,定义导出Excel文件需要的数据,这里提供一个对象数组即可,后面的代码会从该数组中提取需要的数据。实例代码如下:
import ExcelJs from "exceljs";
const mockData = [
{
Name: "Allen",
Gender: "Male",
Height: "175"
},
{
Name: "Tom",
Gender: "Male",
Height: "180"
},
{
Name: "Jane",
Gender: "Female",
Height: "170"
}
];
2. 使用依赖包定义一个对象,后期使用该对象设置参数和导出数据
// 获取sheet对象,设置当前sheet的样式
// showGridLines: false 表示不显示表格边框
let workbook = new ExcelJs.Workbook();
let sheetName = "Allen_test.xlsx";
let sheet = workbook.addWorksheet(sheetName, {
views: [{ showGridLines: false }]
});
// 每一个sheet对象对应一个Excel文件中的表,如果你想子一个Excel中显示多个表,可以定义多个sheet
// let sheet2 = workbook.addWorksheet("Second sheet", { views: [{ showGridLines: false }] });
3. 获取表格数据的header信息
我们在制作Excel表格的时候,一般都需要给每一列设置一个表头,用来说明这一列展示的是什么信息,我们之前只定义了表格数据(前面的对象数组),这里根据表格数据,获取对应的表头信息:
let columnArr = [];
for (let i in mockData[0]) {
let tempObj = { name: "" };
tempObj.name = i;
columnArr.push(tempObj);
}
4. 设置表格顶部的信息及样式
在表格中,顶部可以展示该表格的标题,说明,注意事项等信息。如上图中的“This is the header text” 和“As of: 07/09/2021”。
我们可以使用如下代码进行设置顶部信息,设置过程中,可以定义一个起始单元格,然后从该单元格开始,根据columns和rows数组,以此向右和向下的单元格中进行绘制。
sheet.addTable({
name: `Header`,
ref: "A1", // 头部信息从A1单元格开始显示
headerRow: true,
totalsRow: false,
style: {
theme: "",
showRowStripes: false,
showFirstColumn: true,
width: 200
},
columns: [{ name: "This is the header text" }], // 如果传递多个数组元素,会以此在B1, C3...单元格中绘制
rows: [[`As of: 07/09/2021`]] // 如果传递多个数组元素,会以此在A2, A3...单元格中绘制
});
5. 设置表格的主要数据部分
顶部数据绘制完成之后,下面继续绘制主题的数据部分,这是最关键的,我们导出Excel文件就是为了导出这些数据嘛。
// 设置表格的主要数据部分
let headerName = "RequestsList";
sheet.addTable({
name: headerName,
ref: "A5", // 主要数据从A5单元格开始
headerRow: true,
totalsRow: false,
style: {
theme: "TableStyleMedium2",
showRowStripes: false,
width: 200
},
columns: columnArr ? columnArr : [{ name: "" }], // 把之前定义的表头数据传递进来
rows: mockData.map((e) => {
let arr = [];
for (let i in e) {
arr.push(e[i]);
}
return arr;
})
});
6. 美化数据部分的样式
现在数据可以正常导出了,但是导出的数据样式是比较丑的,可以参考一下代码,优化这部分的样式。对代码不明白可以阅读注释。
// 设置单元格的文字样式
sheet.getCell("A1").font = { size: 20, bold: true };
// 设置每一列的宽度
sheet.columns = sheet.columns.map((e) => {
const expr = e.values[5];
switch (expr) {
case "Name":
return { width: 50 };
case "Gender":
return { width: 40 };
case "Height":
return { width: 30 };
default:
return { width: 20 };
}
});
const table = sheet.getTable(headerName);
for (let i = 0; i < table.table.columns.length; i++) {
// 表格主体数据是从A5开始绘制的,一共有三列。这里是获取A5到,B5,C5单元格,定义表格的头部样式
sheet.getCell(`${String.fromCharCode(65 + i)}5`).font = { size: 12 };
sheet.getCell(`${String.fromCharCode(65 + i)}5`).fill = {
type: "pattern",
pattern: "solid",
fgColor: { argb: "c5d9f1" }
};
// 获取表格数据部分,定义其样式
for (let j = 0; j < table.table.rows.length; j++) {
let rowCell = sheet.getCell(`${String.fromCharCode(65 + i)}${j + 6}`);
rowCell.alignment = { wrapText: true };
rowCell.border = {
bottom: {
style: "thin",
color: { argb: "a6a6a6" }
}
};
}
}
table.commit();
7. 将数据导出Excel,自动下载到本地
现在Excel已经绘制完成了,我们需要把数据导出到本地,代码如下,非常简单:
// 定义下载文件的方法
const writeFile = (fileName, content) => {
const link = document.createElement("a");
const blob = new Blob([content], {
type: "application/vnd.ms-excel;charset=utf-8;"
});
link.download = fileName;
link.href = URL.createObjectURL(blob);
link.click();
};
// 表格的数据绘制完成,定义下载方法,将数据导出到Excel文件
workbook.xlsx.writeBuffer().then((buffer) => {
writeFile(sheetName, buffer);
});
代码总览
到这里就完成了导出Excel的所有工作,这里列出所有代码,方便你进一步参考。
如果你想设置表格的其他属性,可以查看官方文档,我认为是非常详细的。
import React from "react";
import ExcelJs from "exceljs";
const mockData = [
{
Name: "Allen",
Gender: "Male",
Height: "175"
},
{
Name: "Tom",
Gender: "Male",
Height: "180"
},
{
Name: "Jane",
Gender: "Female",
Height: "170"
}
];
const ExportToExcel = () => {
const exportToExcel = (data) => {
let sheetName = "Allen_test.xlsx";
let headerName = "RequestsList";
// 获取sheet对象,设置当前sheet的样式
// showGridLines: false 表示不显示表格边框
let workbook = new ExcelJs.Workbook();
let sheet = workbook.addWorksheet(sheetName, {
views: [{ showGridLines: false }]
});
// let sheet2 = workbook.addWorksheet("Second sheet", { views: [{ showGridLines: false }] });
// 获取每一列的header
let columnArr = [];
for (let i in data[0]) {
let tempObj = { name: "" };
tempObj.name = i;
columnArr.push(tempObj);
}
// 设置表格的头部信息,可以用来设置标题,说明或者注意事项
sheet.addTable({
name: `Header`,
ref: "A1", // 头部信息从A1单元格开始显示
headerRow: true,
totalsRow: false,
style: {
theme: "",
showRowStripes: false,
showFirstColumn: true,
width: 200
},
columns: [{ name: "This is the header text" }, { name: "Hahaha" }],
rows: [[`As of: 07/09/2021`], [`Allen`]]
});
// 设置表格的主要数据部分
sheet.addTable({
name: headerName,
ref: "A5", // 主要数据从A5单元格开始
headerRow: true,
totalsRow: false,
style: {
theme: "TableStyleMedium2",
showRowStripes: false,
width: 200
},
columns: columnArr ? columnArr : [{ name: "" }],
rows: data.map((e) => {
let arr = [];
for (let i in e) {
arr.push(e[i]);
}
return arr;
})
});
sheet.getCell("A1").font = { size: 20, bold: true }; // 设置单元格的文字样式
// 设置每一列的宽度
sheet.columns = sheet.columns.map((e) => {
const expr = e.values[5];
switch (expr) {
case "Name":
return { width: 50 };
case "Gender":
return { width: 40 };
case "Height":
return { width: 30 };
default:
return { width: 20 };
}
});
const table = sheet.getTable(headerName);
for (let i = 0; i < table.table.columns.length; i++) {
// 表格主体数据是从A5开始绘制的,一共有三列。这里是获取A5到,B5,C5单元格,定义表格的头部样式
sheet.getCell(`${String.fromCharCode(65 + i)}5`).font = { size: 12 };
sheet.getCell(`${String.fromCharCode(65 + i)}5`).fill = {
type: "pattern",
pattern: "solid",
fgColor: { argb: "c5d9f1" }
};
// 获取表格数据部分,定义其样式
for (let j = 0; j < table.table.rows.length; j++) {
let rowCell = sheet.getCell(`${String.fromCharCode(65 + i)}${j + 6}`);
rowCell.alignment = { wrapText: true };
rowCell.border = {
bottom: {
style: "thin",
color: { argb: "a6a6a6" }
}
};
}
}
table.commit();
const writeFile = (fileName, content) => {
const link = document.createElement("a");
const blob = new Blob([content], {
type: "application/vnd.ms-excel;charset=utf-8;"
});
link.download = fileName;
link.href = URL.createObjectURL(blob);
link.click();
};
// 表格的数据绘制完成,定义下载方法,将数据导出到Excel文件
workbook.xlsx.writeBuffer().then((buffer) => {
writeFile(sheetName, buffer);
});
};
return (
<button
onClick={() => {
exportToExcel(mockData);
}}
>
Export to Excel
</button>
);
};
export default ExportToExcel;