Node.js利用js-xlsx处理Excel文件的方法详解
简介
本文介绍用 node.js 中的 js-xlsx 库来处理 excel 文件。
js-xlsx 库是目前 github 上 star 数量最多的处理 excel 的库,功能强大,但上手难度稍大。文档有些乱,不适合快速上手。
本文对 js-xlsx 库进行一定的总结,并提供几个实用的例子供读者测试,学习,交流。
安装
$ npm install xlsx
一些概念
在使用这个库之前,先介绍库中的一些概念。
- workbook 对象,指的是整份 excel 文档。我们在使用 js-xlsx 读取 excel 文档之后就会获得 workbook 对象。
- worksheet 对象,指的是 excel 文档中的表。我们知道一份 excel 文档中可以包含很多张表,而每张表对应的就是 worksheet 对象。
- cell 对象,指的就是 worksheet 中的单元格,一个单元格就是一个 cell 对象。
它们的关系如下:
// workbook { sheetnames: ['sheet1', 'sheet2'], sheets: { // worksheet 'sheet1': { // cell 'a1': { ... }, // cell 'a2': { ... }, ... }, // worksheet 'sheet2': { // cell 'a1': { ... }, // cell 'a2': { ... }, ... } } }
用法
基本用法
- 用
xlsx.readfile
打开 excel 文件,返回 workbook - 用
workbook.sheetnames
获取表名 - 用
workbook.sheets[xxx]
通过表名获取表格 - 按自己的需求去处理表格
- 生成新的 excel 文件
具体用法
读取 excel 文件
import xlsx from 'xlsx'; const workbook = xlsx.readfile('someexcel.xlsx', opts);
获取 excel 文件中的表
// 获取 excel 中所有表名 const sheetnames = workbook.sheetnames; // 返回 ['sheet1', 'sheet2'] // 根据表名获取对应某张表 const worksheet = workbook.sheets[sheetnames[0]];
通过 worksheet[address]
来操作表格,以 ! 开头的 key 是特殊的字段。
// 获取 a1 单元格对象 let a1 = worksheet['a1']; // 返回 { v: 'hello', t: 's', ... } // 获取 a1 中的值 a1.v // 返回 'hello' // 获取表的有效范围 worksheet['!ref'] // 返回 'a1:b20' worksheet['!range'] // 返回 range 对象,{ s: { r: 0, c: 0}, e: { r: 100, c: 2 } } // 获取合并过的单元格 worksheet['!merges'] // 返回一个包含 range 对象的列表,[ {s: { r: 0, c: 0 }, c: { r: 2, c: 1 } } ]
实战
解析 excel 生成 json
tips 事实上,你可以直接通过 xlsx.utils.sheet_to_json(worksheet)
获得同样的结果
注意 本例子中假设表的第一行为字段名
const headers = {}; const data = []; const keys = object.keys(worksheet); keys // 过滤以 ! 开头的 key .filter(k => k[0] !== '!') // 遍历所有单元格 .foreach(k => { // 如 a11 中的 a let col = k.substring(0, 1); // 如 a11 中的 11 let row = parseint(k.substring(1)); // 当前单元格的值 let value = worksheet[k].v; // 保存字段名 if (row === 1) { headers[col] = value; return; } // 解析成 json if (!data[row]) { data[row] = {}; } data[row][headers[col]] = value; }); console.log(data); // [ { '姓名': 'test1', '年龄': 20 }, { '姓名': 'test2', '年龄': 10 } ... ]
合并表格
步骤:
- 读取多份表格
- 合并数组
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 | ??? |
let sheet1 = xlsx.utils.sheet_to_json(sheet1); let sheet2 = xlsx.utils.sheet_to_json(sheet2); // 先合并 sheet1 和 sheet2,再对统一处理 const result = sheet1.concat(sheet2).reduce((prev, next) => { let index = prev.findindex((elem, i) => elem.id === next.id); if (index === -1) { return prev.concat(next); } else { prev[index] = object.assign({}, prev[index], next); return prev; } }, []); console.log(result); // [ { 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: '???' } ]
导出表格
步骤:
- 构建特定的数据结构,如下。
- 调用
xlsx.writefile(workbook, filename)
即可。
// workbook { sheetnames: ['mysheet'], sheets: { 'mysheet': { '!ref': 'a1:e4', // 必须要有这个范围才能输出,否则导出的 excel 会是一个空表 a1: { v: 'id' }, ... } } }
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');
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对的支持。
出处
http://scarletsky.github.io/2016/01/30/nodejs-process-excel/
参考资料
https://github.com/sheetjs/js-xlsx
http://*.com/questions/30859901/parse-xlsx-with-node-and-create-json
上一篇: Nodejs之http的表单提交
下一篇: 微信小程序 Buffer缓冲区的详解
推荐阅读
-
详解使用Python处理文件目录的相关方法
-
C#.net编程创建Access文件和Excel文件的方法详解
-
Linux中利用Vim对文件进行密码保护的方法详解
-
利用Shell脚本循环读取文件中每一行的方法详解
-
C#中调用DLL时未能加载文件或程序集错误的处理方法(详解)
-
利用node.js实现自动生成前端项目组件的方法详解
-
Node.js利用console输出日志文件的方法示例
-
利用Python暴力破解zip文件口令的方法详解
-
利用pandas进行大文件计数处理的方法
-
Java利用exe4j工具生成exe文件实例演示,IntelliJ IDEA将项目转化为jar包方法,运行生成后的程序弹出exe4j提示处理