由于一直搞不懂workbook里面的内容,以及在导入导出excel的时候,弄不清楚里面的每一项数据都是干什么的,今天来巴拉巴拉一下vue-element-admin的导入导出
导入
从目录UploadExcel/index.vue中可以找到方法readerData,我们输出了workbook, header, 转json的结果,转html的结果分别如下所示:
workbook
从这里可以拿到SheetNames 也就是我们在一个excel里面开了一个sheet,对应位置如下:
可以拿到Sheets,也就是对应sheetNames下的的内容
header
从代码getHeaderRow中可以看到,对传入的workbook的第一行进行遍历,获取其header
decode_range函数: 将'A1:E21'格式的range转换成对象格式,如下所示:
'A1:E21' => decode_range =>
{
s: {
c: 0, r: 0 // 开始位置单元格[0,0]
},
e: {
c: 4, r: 20 // 结束位置单元格[4,20]
}
}
encode_cell函数: 将单元格坐标位置转换成单元格具体信息
{c:0,r:0} => encode_cell =>{t: 's', v: 'Id', h: 'Id', w: 'Id'}
转json
sheet_to_json函数,可以直接将我们的sheet对象里繁琐的数据结构转换成我们想要的以表头为数组对象,且对象的key,value为对应的表头和行值。
=>
完美,这样,渲染导入的数据的内容就很容易了,直接使用Vue-ElementUI/Plus的el-table就大功告成!!!
vue-element-admin:panjiachen.github.io/vue-element…
到这里其实已经实现了基本的excel表格数据渲染,但我很好奇sheet_to_html生成的html是怎样的,于是又console.log(sheet_to_html(workbook))看了一下,结果如下:
是一段压缩过的html代码!把他复制到网页中,呈现出来了如下页面:
导出
导出的操作基本上可以说是导入操作的逆操作。回顾上面的部分,导入的时候,我们需要去分析workbook, 调用XLSX中的一系列函数,将XLSX语法中的key,key-value转换成我们想要的json格式。那么我们导出,就是要调用XLSX中的一系列的函数,组合表头,表数据,然后转换成XLSX的语法结构。
让我们开始吧!同样的,来看一下vue-admin-template源码里的截图:
这里,我已经注释掉了实现一个简单表导出excel不需要的部分。
- 第一步组合表头和表内容
- 数据格式转换
- writeFile函数,写入并强制导出下载
ok, 这里的关键当然是数据格式转换了,其实实现过程也很简单,截图如下:
这里的range是不是很熟悉,就是前文我们导入时,调用decode_range函数将!ref转换的结果,现在我们去遍历json(这里已经使用扩展运算符由json转换成array了),可以找到表格内容的范围,更新range值,再利用encode_range将其转换回!ref格式A1E21,同样,利用encode_cell可以把之前通过decode_cell解码的坐标转换回原来的格式,再去根据其属性v判断类型从而设置其他属性值,这里每个单元格的属性key对应的解释如下图
| Key | Description |
|---|---|
v | 原始值(查看数据类型部分获取更多的信息) |
w | 格式化文本(如果可以使用) |
t | 内行: b Boolean, e Error, n Number, d Date, s Text, z Stub |
f | 单元格公式编码为 A1 样式的字符串(如果可以使用) |
F | 如果公式是数组公式,则包围数组的范围(如果可以使用) |
r | 富文本编码 (如果可以使用) |
h | 富文本渲染成 HTML (如果可以使用) |
c | 与单元格关联的注释 |
z | 与单元格关联的数字格式字符串(如果有必要) |
l | 单元格的超链接对象 (.Target 长联接, .Tooltip 是提示消息) |
s | 单元格的样式/主题 (如果可以使用) |
这样,我们就能够拿到想要的excel格式的表格内容了。从而往workbook中追加SheetNames和Sheets,再调用writeFile则可以导出内容。
不得不说,xlsx插件的功能真是强大!!
当然到这里还没有完,这个时候,又想到了,如何渲染百万条excel数据, 导出百万条excel数据 怎么办? okay,摸鱼时间结束,下一节继续看..
参考: xlsx: docs.sheetjs.com/docs/api/#u…