在使用elementui做管理平台时遇到导出表格的需求,网上有很多解决方案,最多的就是使用xlsx + FileSaver 将页面上的表格转换成excel book。
这个过程中遇到过两个坑,记录一下。
用到的插件:
// 安装xlsx filesaver
npm install --save xlsx file-saver
封装了一下工具方法
// 纯前端导出 el标识元素id,name为导出文件名
export function exportFileBySelf(el, name) {
let xlsxParam = { raw: true }
const wb = XLSX.utils.table_to_book(document.querySelector(`${el}`),xlsxParam);
const wbout = XLSX.write(wb, {
bookType: "xlsx",
bookSST: true,
type: "array"
});
try {
FileSaver.saveAs(
new Blob([wbout], { type: "application/octet-stream" }),
`${name}.xlsx`
);
Message({
message: "导出成功~",
type: "success"
});
} catch (e) {
if (typeof console !== "undefined") {
Message({
message: "导出失败",
type: "error"
});
console.log(e, wbout);
}
}
return wbout;
}
然而导出一份表格的时候发现一样的数据导了两遍。表头也是两遍
把所有的数据全部都查了一遍发现,我的数据没有重复,展示的table也无重复,再查看element table生成的代码发现: 罪魁祸首是: 如果使用了el-table的fixed属性来让某一列固定,但elementui的实现方式是:创建了两个tabledom,通过一个隐藏一个显示来实现交互效果。当我导出整个el-table 就会将两个div内的table都导出,导致数据重复。 原文链接:www.taodudu.cc/news/show-1…
所以我针对这种情况又做了以下处理:
export const exportTb = (id, title) => {
/* generate workbook object from table */
// 判断要导出的节点中是否有fixed的表格,如果有,转换excel时先将该dom移除,然后append回去
【重点】
var fix = document.querySelector('.el-table__fixed');
var wb;
if (fix) {wb = XLSX.utils.table_to_book(document.querySelector(id).removeChild(fix));
document.querySelector(id).appendChild(fix);
} else {
wb = XLSX.utils.table_to_book(document.querySelector(id));
}
【重点】
/* get binary string as output */
var wbout = XLSX.write(wb,
{bookType: 'xlsx',bookSST: true,type: 'array'});
try {FileSaver.saveAs(new Blob([wbout],
{type: 'application/octet-stream'}),title);
} catch (e) {
if (typeof console !== 'undefined')
console.log(e, wbout);}
return wbout;
};
当然,也可以直接去掉fixed。看个人需求。
还有一个问题是,如果表格中用了slot-scope插槽,然后又搞了条件判断,比如
<template slot-scope="scope">
<span v-show="scope.row.sex == 1">男</span>
<span v-show="scope.row.sex == 2">女</span>
</template>
如果用v-show,就会导致两个都导出到单元格,因为v-show只是隐藏,dom元素实际还是存在的。全部改为v-if即可解决此问题。