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

看一下文件读取的输出结果,Sheets里面包含的是他的全部工作表(Sheet)的数据。里面A1,B1这些对应的都是每个格子的数据,唯独有一个key比较特殊,就是这个 !ref 。这个代表的是这个工作表的数据范围,然后使用数据的时候就可以这样用:
let range = Xlsx.utils.decode_range(wb.Sheets['数据表设定']["!ref"])
s(start_cell):{
c(col):0 , r(row):0} e(end_cell):{
c(col):6 , r(row):42}
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 = wb.Sheets['数据表设定'][cell_ref].v }
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')
后续在使用过程中遇到解决一些问题可能会持续更新。
结语
附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 = 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使用
<Dragger style={
{
width: '100%'}} {...uploadConfigProps} > <p className="ant-upload-drag-icon"> <InboxOutlined />
p> <p className="ant-upload-text">点击或拖动文件至该区域上传
p>
Dragger>
Upload的代码也是基本类似的,这里我加上了return Upload.LIST_IGNORE;这个返回值可以使得上传的文件不会出现在Upload的上传队列里面同时showUploadList={false}这个代码也是同样的效果,请注意甄别。
{ console.log(file) return Upload.LIST_IGNORE; }} >
<a>重新上传
a>
Upload>
附2:如何在多个文件全部读取完之后再进行下一步操作
发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/216791.html原文链接:https://javaforall.net
