用exceljs实现Json对象导出excel

背景

在做随手记账本项目的时候,很多网友在意见反馈中建议提供导出功能。由于小程序的后台是基于node的,于是在npm里找了下关于excel的包,也参考了百度建议,推荐比较多的是excelexport,但是我最后选了exceljs。主要是一直在持续更新,文档也很全面。

思路

由于后台数据库保存的账本数据是采用json格式的,最简单的方法就是通过遍历账本中的所有条目逐行写入excel。但是发现在exceljs这个包中,是提供列定义的,通过定义每列的key,就可以直接把json数据写入了,这个功能非常赞。

这部分的文档说明如下:

1
2
3
4
5
6
7
8
9
10
11
12
// Add column headers and define column keys and widths
// Note: these column structures are a workbook-building convenience only,
// apart from the column width, they will not be fully persisted.
worksheet.columns = [
{ header: 'Id', key: 'id', width: 10 },
{ header: 'Name', key: 'name', width: 32 },
{ header: 'D.O.B.', key: 'DOB', width: 10, outlineLevel: 1 }
];

// Add a couple of Rows by key-value, after the last current row, using the column keys
worksheet.addRow({id: 1, name: 'John Doe', dob: new Date(1970,1,1)});
worksheet.addRow({id: 2, name: 'Jane Doe', dob: new Date(1965,1,7)});

需要说明的说,文档里定义的column里的header,会自动写在表格的第一行当做表头,不需要另起一行。

实现

主要有这么几个步骤:

  • 新建workbook对象
  • 新建sheet
  • 定义column
  • 写入row
  • 导出

代码如下:

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
const Excel = require('exceljs')
// 测试数据
let data = {
"subtitle":"偶遇美食节",
"comment":"鲷鱼烧,烤鱼,年糕丸子。600+200+350",
"cost":1150,
"date":"2018-01-20",
"time":"14:24",
"member":1,
"type":"餐饮",
"currency":"日元",
"location":"Ueno Park (上野恩賜公園)"
}
// 新建workbook对象
let workbook = new Excel.Workbook()
// 设置workbook属性,比如作者
workbook.creator = 'ToRandom'
// 新建sheet
let tempWorksheet = workbook.addWorksheet('东京之旅')
// 定义column, 日期比较长,设置为15 可以展示yyyy-mm-dd
tempWorksheet.columns = [
{header: '标题', key: 'subtitle'},
{header: '消费类型', key: 'type'},
{header: '评论', key: 'comment'},
{header: '币种', key: 'currency'},
{header: '费用', key: 'cost'},
{header: '日期', key: 'date', width: 15},
{header: '时间', key: 'time'},
{header: '人数', key: 'member'},
{header: '位置信息', key: 'location'}
]
// 写入
tempWorksheet.addRow(data)
// 保存文件,如有需要,前面加await等待执行
workbook.xlsx.writeFile("随手记账本.xlsx)

注意

  • 一般node默认是异步执行的,如有后续操作(比如先生成excel文件之后,以附件的形式发送),那么就需要在最后一步保存文件的代码前面加上await
1
await workbook.xlsx.writeFile("随手记账本.xlsx")
  • 如果生成之后,处理完了要删除的话,可以使用fs.unlink来删除。但注意的是,这个unlink也是一个异步函数,删除效果会有延迟。
  • 其他关于exceljs的操作,可以参考原文档,还是相当丰富的。

https://www.npmjs.com/package/exceljs