背景:
我的项目用的是iview-admin2.0框架,里面将iview进行了升级,而且表格里用到了fiexd,对特殊的列进行了浮动。
需求是要求前端进行表格导出,而且要带边框。
用到了如下技术;
import FileSaver from “file-saver”;
import XLSX from “xlsx”;
import xlsxStyle from “xlsx-style”;
import XSU from “./xlsxStyle.utils”;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
步骤如下:
1.直接npm 分别安装 FileSaver、XLSX、xlsxStyle
FileSaver、XLSX、xlsxStyle可以直接npm;
XSU是git上下载下来的静态资源(https://github.com/Ctrl-Ling/XLSX-Style-Utils),别人封装的方法。
此处不详细贴代码了;
import XLSX from “xlsx-style”
2.我新增加了一个tool.js
在这个js里
import FileSaver from “file-saver”;
import XLSX from “xlsx”;
import xlsxStyle from “xlsx-style”;
import XSU from “./xlsxStyle.utils”;
引入第三个xlsx-style的时候会报错:
This relative module was not found: ./cptable in ./node_modules/[email protected]@xlsx-style/dist/cpexcel.js
需要修改源码:
在\node_modules\xlsx-style\dist\cpexcel.js 807行 的 var cpt = require(’./cpt’ + ‘able’); 改成 var cpt = cptable;(不要因为乱码就不往下了,往下翻)
第四个就是从上面说到的静态资源的链接里down的资源,将里面的xlsxStyle.utils.js放到本地的文件夹里,tool.js 这里要能引到。
我这边放在了同级别目录下;
当然,xlsxStyle.utils.js 文件最下面
别忘了添加 export default XSU;
3.tool.js里添加方法,可以多处导出使用
方法如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | export const exportExcel = (function (id,name) { return new Promise((resolve, reject) => { /* 从表生成工作簿对象 */ // 判断要导出的节点中是否有fixed的表格,如果有,转换excel时先将该dom移除,然后append回去, let fix = document.querySelector('.ivu-table-fixed-right'); let wb if (fix) { document.querySelector('#' + id).children[0].removeChild(fix); wb = XLSX.utils.table_to_book(document.querySelector('#' + id)); document.querySelector('#' + id).children[0].appendChild(fix); } else { wb = XLSX.utils.table_to_book(document.querySelector('#' + id)); } var sheetName = wb.SheetNames[0]; for (let key in wb.Sheets.Sheet1) { if (Object.prototype.toString.call(wb.Sheets.Sheet1[key]) === '[object Object]'){ wb.Sheets.Sheet1[key].v = wb.Sheets.Sheet1[key].v.toString().replace(/\s+/g, ""); //我的表格里针对fixed属性的一列,不需要导出,没有想到别的好的办法,就直接置空了。我用这个方法导出时,在表达的最下面一行会有'暂无筛选结果',没有找到原因,所以也直接置空。 if (wb.Sheets.Sheet1[key].v == '暂无筛选结果' || wb.Sheets.Sheet1[key].v == '修改' || wb.Sheets.Sheet1[key].v == '管理' || wb.Sheets.Sheet1[key].v== '操作') { wb.Sheets.Sheet1[key].v = '' }else { //置空的表格的单元格不需要增加边框,故else的时候给单元格增加边框 XSU.setBorderDefault(wb, sheetName, key) } } } var wbout = xlsxStyle.write(wb, { bookType: "xlsx", bookSST: false, type: 'binary' }); try { FileSaver.saveAs( //Blob 对象表示一个不可变、原始数据的类文件对象。 //Blob 表示的不一定是JavaScript原生格式的数据。 //File 接口基于Blob,继承了 blob 的功能并将其扩展使其支持用户系统上的文件。 //返回一个新创建的 Blob 对象,其内容由参数中给定的数组串联组成。 new Blob([s2ab(wbout)], { type: "" }), //设置导出文件名称 name + ".xlsx" ); } catch (e) { if (typeof console !== "undefined") console.log(e, wbout); } resolve(wbout) }) }) |
在导出方法里还用到了 s2ab的方法,直接在该方法的上面添加即可;
1 2 3 4 5 6 7 | function s2ab(s) { var buf = new ArrayBuffer(s.length); var view = new Uint8Array(buf); for (var i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF; return buf; } |
截图如下:
最后步骤:
在你要用到的组件里
// 引入导出Excel表格
1 | import { exportExcel } from "@/libs/tools"; |
methods里写到:
1 2 3 | exportExcel() { exportExcel("out-table", "项目推进情况"); }, |
PS:
主要是要表格边框,如果不要边框的话就比较简单,几行代码就搞定了。
如有更简单或者其他好的方法,希望可以留言。
灵感来自以下:
https://www.cnblogs.com/lvsk/p/11970747.html
https://github.com/Ctrl-Ling/XLSX-Style-Utils
https://github.com/SheetJS/sheetjs