2024-05-03 11:47:38

在开发需求中,经常会遇到需要和excel相关的需求,毕竟不是所有人都是程序员,很多的业务都是通过excel去进行数据的整理归类计算的,excel中提供的一系列快捷功能,统计功能也非常的实用,但是这也就造成了除了和接口打交道,前端也需要和excel打一下交道

excel 是什么

excel是微软出的一款电子表格软件,wps是国内知名的免费办公软件,以及苹果的Numbers同样都支持编辑和生成excel文件

excel 的格式

这里说的不是单纯的excel而是平时前端开发的时候所使用到的**excel类型**的文件格式,主要有

csv

csv 是一种纯文本的格式,非常的简单,每一行代表一行,没一列通过,进行分割,我们只需要通过split函数就能直接分割成对应的二维数组结构

xsls/xls

区别在于 xls类型的文件我们可以通过存储网页的形式存储下来,xsls就是一个纯的二进制文件了,这一类更倾向于使用类库进行操作

读取

如果是csv,最简单的情况下,就直接使用<input type="file">,只有用fileReader读取为纯文本就行了

nodejsbrowser唯一的区别就在于,node还支持直接通过steam等概念进行输入,而browser只有arrayBuffer这一种手段

在一般情况下,直接fileReader读取excel都会是二进制流,不过根据其编码规范是可以进行还原的,其中的对应关系比较负责

常用的库

库的左右就在于,他们能将excel的文件专为对应的js对象供我们操作

sheet.js

社区开源版本的xlsx.js就可以完成读取和写入的工作了,

以下是 sheet.js 的对应数据结构.

读取也狠方便

1
2
3

XLSX.read(buffer, { type: "buffer" });

不过官方的文档相对还是比较难以理解的,一般日常我用另外一个库

exceljs

js-xlsx 的 思想构成也是通过将二进制流转为js对象的方式方便我们操作,不过 api 方面设计的更加友好一点

最主要的两点。

  • 中文文档

  • demo 易懂

读取也很容易,通过fileReader.readAsArrayBuffer 就能直接读取,如果是在node环境下,更能直接通过steamfile接口直接获取数据

1
2
3
4
5
6
7
8
9
10
11
12
13

// load from buffer

var workbook = new Excel.Workbook();

workbook.xlsx.load(data)

.then(function() {

// use workbook

});

写入

原生 js

这个只适用于 js

xls

2013 之前的xls模式是可以将一个html文件导出成一个.xls文件的所以我们首先定义一个html

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
45

<table id="tblData">

<tr>

<th>Name</th>

<th>Email</th>

<th>Country</th>

</tr>

<tr>

<td>John Doe</td>

<td>john@gmail.com</td>

<td>USA</td>

</tr>

<tr>

<td>Michael Addison</td>

<td>michael@gmail.com</td>

<td>UK</td>

</tr>

<tr>

<td>Sam Farmer</td>

<td>sam@gmail.com</td>

<td>France</td>

</tr>

</table>

接着获取html之后导出

1
2
3
4
5
6
7

const tableHTML = table.outerHTML.replace(/ /g, "%20");

const url = `data:application/vnd.ms-excel,${tableHTML}`;

window.open(url);

csv

还能说什么呢,拼接字符串呗

sheet.js

抱歉不是很熟悉他的输出,可以这样使用来生成一个base64从而用 fileSaver 进行下载

1
2
3

XLSX.write(wb, { bookType: "xlsx", type: "base64" });

exceljs

exceljs 是我最喜欢使用的一个库了,文档清晰而且支持图片,富文本等各种操作

导出

导出操作在浏览器端依然是生成一个ArrayBuffer废话少说,直接上代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

function download(workbook, name = "template") {

if (!workbook) {

throw new Error("workbook不能为空");

}

return workbook.xlsx

.writeBuffer()

.then(buffer => new Blob([buffer], { type: "application/octet-stream" }))

.then(blob =>

FileSaver(blob, `${name}-${new Date().toLocaleString()}.xlsx`)

);

}

填充数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

var worksheet = workbook.addWorksheet("sheet");

worksheet.columns = [

{ header: "Id", key: "id", width: 10 },

{ header: "Name", key: "name", width: 32 },

{ header: "D.O.B.", key: "DOB", width: 10, outlineLevel: 1 }

];



worksheet.addRows([]);

其他操作

文档中已经很详细了,exceljs几乎支持了所有可能会用到的excel操作,建议熟悉文档即可,像合并单元格背景图片富文本评论均可以支持

暂不展开了

ejs-excel

如果熟悉ejs,同时对样式操作,可视化操作的人,可以试试这个,可惜只支持node环境,通过ejs的语法定义,将数据填充到 excel 中并且生成

=>

插件

微软官方文档

excel2016 之后其实 excel 支持使用 js 进行插件的开发,之前工作中遇到过,但是当时不是很完善,等待重新读一遍文档再补充

参考

[SheetJS] js-xlsx 模块学习指南