前端导出 Excel(CSV)文件

在项目中,有时候需要把一些数据导出到一个 Excel 文件中,这里记录下导出方案。

首先我们需要了解什么是 CSV(Comma-Separated Values) 文件:

CSV 是逗号分隔文件(Comma Separated Values)的首字母英文缩写,是一种用来存储数据的纯文本格式,通常用于电子表格或数据库软件。在 CSV 文件中,数据“栏”以逗号分隔,可允许程序通过读取文件为数据重新创建正确的栏结构,并在每次遇到逗号时开始新的一栏。

比如:

1
2
3
4
order,name,age,sex
1,张三,20,男
2,李四,30,女
3,王五,27,女

所以,要把一些数据导出到文件只要转换成这种数据格式即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
let base = {
header: ["order", "name", "age", "sex"],
data: [
{
order: 1,
name: "张三",
age: "11",
sex: "男",
},
{
order: 2,
name: "李四",
age: "33",
sex: "男",
},
{
order: 3,
name: "王五",
age: "32",
sex: "女",
},
],
};

然后将对象转换成 CSV 字符串,代码如下:

1
2
3
4
5
6
7
8
9
function toCSVFile(obj) {
let header = obj.header.join(",") + "\n";
let datas = obj.data.map((ele) => {
return `${ele.order},${ele.name},${ele.age},${ele.sex}\n`;
});
let dataStrs = [header, ...datas].join("");
return dataStrs;
}
toCSVFile(base);

把字符串导出文件,可以使用 Blob 对象,通过 Blob 对象生成一个 URL,然后创建一个 a 标签,达到下载文件的目的。代码中的 \uFEFF 是一个文件头,表示文件的编码,不加这个头,通过某些软件打开时可能会发生乱码。

1
2
3
4
// 创建一个 Blob 对象
const blob = new Blob(["\uFEFF" + dataStrs], {
type: "text/plain;charset=utf-8",
});

创建一个 a 标签,用于下载 Blob 文件:

1
2
3
4
5
6
7
8
const link = document.createElement("a");
link.href = URL.createObjectURL(blob);

// 文件名
link.download = "测试文件.csv";
link.click();
// 需要释放 URL
URL.revokeObjectURL(link.href);

完整代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
let base = {
header: ["order", "name", "age", "sex"],
data: [
{
order: 1,
name: "张三",
age: "11",
sex: "男",
},
{
order: 2,
name: "李四",
age: "33",
sex: "男",
},
{
order: 3,
name: "王五",
age: "32",
sex: "女",
},
],
};

function toCSVFile(obj) {
let header = obj.header.join(",") + "\n";
let datas = obj.data.map((ele) => {
return `${ele.order},${ele.name},${ele.age},${ele.sex}\n`;
});
let dataStrs = [header, ...datas].join("");
// 创建一个 Blob 对象
const blob = new Blob(["\uFEFF" + dataStrs], {
type: "text/plain;charset=utf-8",
});
const link = document.createElement("a");
link.href = URL.createObjectURL(blob);

// 文件名
link.download = "测试文件.csv";
link.click();
// 需要释放 URL
URL.revokeObjectURL(link.href);
}
toCSVFile(base);