网页|SheetJS xlsx js库入门使用


文章目录

  • 1.流式读取文件
  • 2.读取单元格
  • 3.修改单元格
  • 4.保存文件
  • 结语
  • 附1:搭配ANTD的Upload实现流式上传读取
  • 附2:如何在多个文件全部读取完之后再进行下一步操作

最近在用SheetJS这个库,简单记录一下使用成果。
项目地址:
https://github.com/SheetJS/sheetjs
1.流式读取文件 我写的是网页而不是node脚本,所以配合了Antd的Upload组件来做文件上传和文件的流式读取,如果你想看整个的结合方式可以在目录里面跳转到附1部分。
reader.readAsArrayBuffer(dataFileList[key].file); reader.onload = (e)=>{ let data = https://www.it610.com/article/e.target.result; let wb = Xlsx.read(data); console.log(wb); }; reader.onerror = (e) => { isReadFileError = true };

网页|SheetJS xlsx js库入门使用
文章图片

看一下文件读取的输出结果,Sheets里面包含的是他的全部工作表(Sheet)的数据。里面A1,B1这些对应的都是每个格子的数据,唯独有一个key比较特殊,就是这个 !ref 。这个代表的是这个工作表的数据范围,然后使用数据的时候就可以这样用:
let range = Xlsx.utils.decode_range(wb.Sheets['数据表设定']["!ref"])

range经过解码后可以获得开始单元格(cell)和结束单元格的坐标(说实话这个库的api设计的还是比较随便,名字都是起的怪怪的)。
看下面这个图:
网页|SheetJS xlsx js库入门使用
文章图片

s(start_cell):{c(col):0 , r(row):0} e(end_cell):{c(col):6 , r(row):42}

这个表的数据范围就很清楚了,左上角就是A1,0行0列单元格。右下角就是42行6列单元格(当然,数据下标从0开始是我们程序员的思维,如果你需要把这个设定数据传达给一般使用者,记得加一)。
那有了一个表的范围后我们就可以遍历这些个表格了。
2.读取单元格 现在你回想一下上面我们输出的工作表格式,你就会知道我们在读取单元格的时,需要输入他在Excel里面对应的编码,比如读取1行1列的格子,我们就需要输入’A1’这个key来读取。那一个字符串显然是难以进行遍历操作的,XLSX库里面就给我们提供了一个转换的工具类。
for(let C = range.s.c; C <= range.e.c; ++C) { // c col r row let cell_address = {c:C, r:1}; // 将坐标转换成EXCEL的坐标比如{1, 1}转为A1 let cell_ref = Xlsx.utils.encode_cell(cell_address); let value = https://www.it610.com/article/wb.Sheets['数据表设定'][cell_ref].v }

搭配我们上面说到的!ref我们就可以循环遍历这个表了。
然后这里有一个你需要非常注意的点,我们来看一下cell的输出结构:
你会发现他是有一堆东西的,我现在只用到了vt
我这里要提醒你的是,读取完之后你只是获得了这个cell的对象,具体的数值你还需要往下调用一个.v,我这个记性不好,好几次都是这个问题。
t type: b Boolean, e Error, n Number, d Date, s Text, z Stub
v raw value (see Data Types section for more info)
r rich text encoding (if applicable)
h HTML rendering of the rich text (if applicable)
w formatted text (if applicable)
直接访问下面的链接可以看到全部的数据信息
https://github.com/SheetJS/sheetjs#cell-object
网页|SheetJS xlsx js库入门使用
文章图片

3.修改单元格 文档链接:
https://github.com/SheetJS/sheetjs#modifying-cell-values
这个我主要是用到XLSX.utils.sheet_add_aoa这个函数。
当你修改单个单元格:
XLSX.utils.sheet_add_aoa(worksheet, [[new_value]], { origin: address });
修改多个单元格:
XLSX.utils.sheet_add_aoa(worksheet, aoa, opts);
说实话他这个文档写的我是真看不懂,我们直接来研究他给的代码实例:
XLSX.utils.sheet_add_aoa(worksheet, [ [1],// <-- 把1写入到B3里面 ,// <-- 第4行啥也不做 [/*B5*/, /*C5*/, /*D5*/, "abc"]// <-- 把abc写到E5里面 ], { origin: "B3" });

聪明的你一看这个代码就能看懂了吧,也明白了为什么单个单元格用的是 [[new_value]]
4.保存文件 文档链接:
https://github.com/SheetJS/sheetjs#parsing-workbooks
保存文件目前我只测试了最简单的这个writeFile就是直接将wb写成xlsx的,保存文件后会自动弹出下载窗口。
Xlsx.writeFile(configWb, 'test.xlsx')

后续在使用过程中遇到解决一些问题可能会持续更新。
结语 毕竟用js来做数据分析的人比较少,所以库的使用比起pandas那是不方便多了。但是python的传播行在非IT公司还是比较麻烦的,环境打包运行也很慢,所以还是尝试用js来做这个,看看后续能不能将一些简答的pandas的功能稍微实现一下。
顺便在这里记录一个库,https://github.com/davidchambers/string-format。可以让js比较像python一样使用formate字符串拼接,这点也是我想不明白的,python的formate这么好用,为啥js的原生的这么难用,不学习一下吗?
写代码有所进步真的能令人开心呢,我是llsxily,你可以叫我橘子。
附1:搭配ANTD的Upload实现流式上传读取 简单来说思路就是调用Upload的beforeUpload方法,在文件上传前获取到文件,获取到文件后就可以将数据读取到Buffer然后调用Xlsx.read解析xlsx文件。
const uploadConfigProps = { name: 'file', maxCount: 1, beforeUpload: file => { console.log(file) const reader = new FileReader(); reader.readAsArrayBuffer(file); reader.onload = (e) => { console.log('read_file') let data = https://www.it610.com/article/e.target.result; console.log(data) let wb = Xlsx.read(data) console.log(wb) // !ref获取的是表格的规模大小 let range = Xlsx.utils.decode_range(wb.Sheets['数据表设定']["!ref"]) console.log(range) ... } } return false; } }

这个是配合Dragger使用

点击或拖动文件至该区域上传

Upload的代码也是基本类似的,这里我加上了return Upload.LIST_IGNORE; 这个返回值可以使得上传的文件不会出现在Upload的上传队列里面同时showUploadList={false}这个代码也是同样的效果,请注意甄别。
{ console.log(file) return Upload.LIST_IGNORE; }} > 重新上传

附2:如何在多个文件全部读取完之后再进行下一步操作 【网页|SheetJS xlsx js库入门使用】这个功能可以查看我上一篇文章
React-js中等待多个回调全部完成后执行后续函数

    推荐阅读