在 Node.js 中利用 js-xlsx 处理 Excel 文件
文章目录
简介
本文介绍用 Node.js 中的 js-xlsx
库来处理 Excel 文件。
js-xlsx
库是目前 Github 上 star 数量最多的处理 Excel 的库,功能强大,但上手难度稍大。文档有些乱,不适合快速上手。
本文对 js-xlsx
库进行一定的总结,并提供几个实用的例子供读者测试,学习,交流。
安装
|
|
一些概念
在使用这个库之前,先介绍库中的一些概念。
workbook
对象,指的是整份 Excel 文档。我们在使用js-xlsx
读取 Excel 文档之后就会获得workbook
对象。worksheet
对象,指的是 Excel 文档中的表。我们知道一份 Excel 文档中可以包含很多张表,而每张表对应的就是worksheet
对象。cell
对象,指的就是worksheet
中的单元格,一个单元格就是一个cell
对象。
它们的关系如下:
|
|
用法
基本用法
- 用
XLSX.readFile
打开 Excel 文件,返回workbook
- 用
workbook.SheetNames
获取表名 - 用
workbook.Sheets[xxx]
通过表名获取表格 - 按自己的需求去处理表格
- 生成新的 Excel 文件
具体用法
读取 Excel 文件
|
|
获取 Excel 文件中的表
|
|
通过 worksheet[address]
来操作表格,以 !
开头的 key 是特殊的字段。
|
|
实战
解析 Excel 生成 JSON
Tips 事实上,你可以直接通过
XLSX.utils.sheet_to_json(worksheet)
获得同样的结果
注意 本例子中假设表的第一行为字段名
|
|
合并表格
步骤:
- 读取多份表格
- 合并数组
Tips: 其实合并表格跟 XLSX
没什么关系,只是处理几个数组而已。
sheet1
id | name | age |
---|---|---|
1 | test1 | 30 |
2 | test2 | 20 |
3 | test3 | 18 |
sheet2
id | country | remark |
---|---|---|
1 | China | hello |
2 | America | world |
3 | Unkonw | ??? |
|
|
导出表格
步骤:
- 构建特定的数据结构,如下。
调用
XLSX.writeFile(workbook, filename)
即可。1 2 3 4 5 6 7 8 9 10 11
// workbook { SheetNames: ['mySheet'], Sheets: { 'mySheet': { '!ref': 'A1:E4', // 必须要有这个范围才能输出,否则导出的 excel 会是一个空表 A1: { v: 'id' }, ... } } }
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 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
var _headers = ['id', 'name', 'age', 'country', 'remark'] var _data = [ { id: '1', name: 'test1', age: '30', country: 'China', remark: 'hello' }, { id: '2', name: 'test2', age: '20', country: 'America', remark: 'world' }, { id: '3', name: 'test3', age: '18', country: 'Unkonw', remark: '???' } ]; var headers = _headers // 为 _headers 添加对应的单元格位置 // [ { v: 'id', position: 'A1' }, // { v: 'name', position: 'B1' }, // { v: 'age', position: 'C1' }, // { v: 'country', position: 'D1' }, // { v: 'remark', position: 'E1' } ] .map((v, i) => Object.assign({}, {v: v, position: String.fromCharCode(65+i) + 1 })) // 转换成 worksheet 需要的结构 // { A1: { v: 'id' }, // B1: { v: 'name' }, // C1: { v: 'age' }, // D1: { v: 'country' }, // E1: { v: 'remark' } } .reduce((prev, next) => Object.assign({}, prev, {[next.position]: {v: next.v}}), {}); var data = _data // 匹配 headers 的位置,生成对应的单元格数据 // [ [ { v: '1', position: 'A2' }, // { v: 'test1', position: 'B2' }, // { v: '30', position: 'C2' }, // { v: 'China', position: 'D2' }, // { v: 'hello', position: 'E2' } ], // [ { v: '2', position: 'A3' }, // { v: 'test2', position: 'B3' }, // { v: '20', position: 'C3' }, // { v: 'America', position: 'D3' }, // { v: 'world', position: 'E3' } ], // [ { v: '3', position: 'A4' }, // { v: 'test3', position: 'B4' }, // { v: '18', position: 'C4' }, // { v: 'Unkonw', position: 'D4' }, // { v: '???', position: 'E4' } ] ] .map((v, i) => _headers.map((k, j) => Object.assign({}, { v: v[k], position: String.fromCharCode(65+j) + (i+2) }))) // 对刚才的结果进行降维处理(二维数组变成一维数组) // [ { v: '1', position: 'A2' }, // { v: 'test1', position: 'B2' }, // { v: '30', position: 'C2' }, // { v: 'China', position: 'D2' }, // { v: 'hello', position: 'E2' }, // { v: '2', position: 'A3' }, // { v: 'test2', position: 'B3' }, // { v: '20', position: 'C3' }, // { v: 'America', position: 'D3' }, // { v: 'world', position: 'E3' }, // { v: '3', position: 'A4' }, // { v: 'test3', position: 'B4' }, // { v: '18', position: 'C4' }, // { v: 'Unkonw', position: 'D4' }, // { v: '???', position: 'E4' } ] .reduce((prev, next) => prev.concat(next)) // 转换成 worksheet 需要的结构 // { A2: { v: '1' }, // B2: { v: 'test1' }, // C2: { v: '30' }, // D2: { v: 'China' }, // E2: { v: 'hello' }, // A3: { v: '2' }, // B3: { v: 'test2' }, // C3: { v: '20' }, // D3: { v: 'America' }, // E3: { v: 'world' }, // A4: { v: '3' }, // B4: { v: 'test3' }, // C4: { v: '18' }, // D4: { v: 'Unkonw' }, // E4: { v: '???' } } .reduce((prev, next) => Object.assign({}, prev, {[next.position]: {v: next.v}}), {}); // 合并 headers 和 data var output = Object.assign({}, headers, data); // 获取所有单元格的位置 var outputPos = Object.keys(output); // 计算出范围 var ref = outputPos[0] + ':' + outputPos[outputPos.length - 1]; // 构建 workbook 对象 var wb = { SheetNames: ['mySheet'], Sheets: { 'mySheet': Object.assign({}, output, { '!ref': ref }) } }; // 导出 Excel XLSX.writeFile(wb, 'output.xlsx');
参考资料
文章作者 scarletsky
上次更新 2019-04-30 (95a170d)