4行代码实现vue + element ui的表格数据导出为xlsx文件
需求说明
前台页面通过表格呈现查询数据,并由一个按钮点击事件将表格的数据以xlsx的文件格式导出下载。
开发环境
Chrome + vue 2.0 + Element UI
方案1:XLSX + FILE-SAVER
因为文件下载需求的普遍性,以及vue和Element的流行性,网上相似的方案很多。稍作整理后的形式如下:
// 导出按钮绑定的函数exportXLSX() { // 从表格生成workbook let wb = XLSX.utils.table_to_book(document.querySelector('#tableID')); let wbout = XLSX.write(wb, { bookType: "xlsx", bookSST: true, type: "array" }); try { // 下载 let b = new Blob([wbout], { type: "application/octet-stream" }); FileSaver.saveAs(b, "filename.xlsx"); } catch (e) { if (typeof console !== "undefined") { console.log(e, wbout); } } return wbout;}该函数流程大致为:
- 通过ID找到表格
- 利用XLSX的table_to_book方法将表格数据直接生成到工作簿
- 将工作簿包装为blob对象
- 通过FileSaver实现文件保存功能
问题1:可能导出重复数据
当使用Element UI的el-table中的fixed属性时,实际生成了2张表格,因而以上方案导出的数据会出现重复的现象。就像这样:
重复的数据
既然起因很清楚了,那么这个问题的处理办法也容易找到:在生成工作簿的时候,首先去除带有fix属性的表格,在工作簿对象生成后再增加上。
这样,生成工作簿的代码升级为:
let fix = document.querySelector('.el-table__fixed');if (fix) { let wb = XLSX.utils.table_to_book(document.querySelector('#tableID').removeChild(fix)); document.querySelector('#tableID').appendChild(fix);} else { let wb = XLSX.utils.table_to_book(document.querySelector('#tableID'));}问题2:分页数据只导出页面显示的部分
假如表格存在分页,上述方法导出的是当前显示的部分。网上也有几种处理办法:
- 前台隐藏一个全量的table,专门用于导出(个人不推荐)。
- 导出的时候临时修改pageSize,使全量数据都在表格上。完成后复原。
这两个我都没尝试,也就不贴代码了,通过搜索都可以找到。
方案2:只使用XLSX处理问题
之前两个问题的处理办法要么触发了前台变更的操作,要么保存了多余的内容。尽管能处理问题,但总有些变扭。
重新看了看SheetJS项目的文档,发现有json_to_sheet方法,官方的示例如下:
var ws = XLSX.utils.json_to_sheet([ { S:1, h:2, e:3, e_1:4, t:5, J:6, S_1:7 }, { S:2, h:3, e:4, e_1:5, t:6, J:7, S_1:8 }], {header:["S","h","e","e_1","t","J","S_1"]});假如不显式定义列名,则以第一个对象的Object.keys作为列名。
The default column order is determined by the first appearance of the field using Object.keys
这不正和el-table的表单数据格式一模一样么。本地已经有tableData,且是全量数据,不存在分页问题,直接用tableData加上json_to_sheet方法生成sheet便可。但这个方法返回的是worksheet,而非workbook,因而需要增加到一个workbook。最后使用workbook的writeFile方法就可完成下载。最终代码如下:
exportXLSX() { let ws = XLSX.utils.json_to_sheet(this.tableData); let wb = XLSX.utils.book_new(); XLSX.utils.book_append_sheet(wb, ws, 'sheetname'); return XLSX.writeFile(wb, 'filename.xlsx'); }代码可以如此简洁,且用不着file-saver的起因是,其实writeFile方法包装了很多行为,包括使浏览器生成文件的链接并强制点击,触发文件保存的动作等。
XLSX.writeFile wraps a few techniques for triggering a file save:
- URL browser API creates an object URL for the file, which the library uses by creating a link and forcing a click. It is supported in modern browsers.
- msSaveBlob is an IE10+ API for triggering a file save.
- IE_FileSave uses VBScript and ActiveX to write a file in IE6+ for Windows XP and Windows 7. The shim must be included in the containing HTML page.
不知道这样的兼容性如何,至少Chrome 80版本完全可行。
参考
- SheetJS js-xlsx的git库
- Element-ui组件库Table表格导出Excel表格
- 记element + xlsx 导出表格数据重复的坑
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » 4行代码实现vue + element ui的表格数据导出为xlsx文件