使用js | 您所在的位置:网站首页 › 重工业对环境的污染 › 使用js |
前言
最近公司需要将几张统计表格导出到excel,由于公司现有导出excel功能是前后端配合的导出,觉得麻烦,所以想找一个纯前端导出的工具,最后找到了js-xlsx,评价还是挺高的,但是中文文档没找到,百度也没有找到一个比较全面的教程,所以踩了很多坑,自己记录下,方便以后使用。 环境由于我业务只用到将table标签内的内容导出到excel,所以只会写如何将一个table元素里的内容导出到excel。也可以通过json导出,貌似还会更简单些。 安装GitHub地址 npm安装 npm install xlsx安装后dist文件夹下有一个文件xlsx.full.min.js,就是它了,引入到项目中 第一个例子先上代码 Document 序号 姓名 年龄 兴趣 1 张三 18 打游戏 2 李四 88 看电影 3 王五 81 睡觉 导出 function btn_export() { var table1 = document.querySelector("#table1"); var sheet = XLSX.utils.table_to_sheet(table1);//将一个table对象转换成一个sheet对象 openDownloadDialog(sheet2blob(sheet),'下载.xlsx'); }运行效果 导出结果:
PS: 这2个方法是网上当的,原文地址。作者写的挺好,也是从这里找到了头绪。 如果你的table标签内有合并单元格的操作,XLSX.utils.table_to_sheet(*)也能够读取出来,并且你打印出来的结果也能够显示出来,效果图: 这里就不绕圈子了,设置样式的话,上面的xlsx.full.min.js是无法生效的, 必须安装xlsx-style 安装xlsx-style好像只有npm安装,github我没找到地址 npm install xlsx-style同样,安装目录下dist文件夹下有一个xlsx.full.min.js,嗯?名字一模一样?怎么用?好吧,无从下手,只好硬着头皮引入了,注意,我将xlsx-style的js文件放在下方: 改完之后,点击运行,果不其然,报错了: 原因是什么呢,原因是2个js文件暴露出来的变量都叫‘XLSX’,但是xlsx-style这个js文件里没有XLSX.utils这个方法,而且xlsx-style这个js文件是后引入的,就把前面的XLSX给覆盖了,所以报错。 XLSX.utils里面有很多可用的方法,但是按照这种方式无法进行调用: 不用XLSX.utils的方式 由于这2个js都是加密之后的内容,无法解读,不能在这2个js上找到什么有用的东西。好在在xlsx dist文件夹下找到了xlsx.extendscript.js,看这个文件就像个工具类,由于我上面用到了table_to_sheet方法,在xlsx.extendscript上面的搜索了一下,果然发现了这个方法,二话不说,将xlsx的js引用删除,引入xlsx.extendscript: 运行。结果你应该已经猜到了,样式并没有发生改变。什么原因呢,xlsx.extendscript.js暴露出来的变量仍然是’XLSX’,下面的变量还是覆盖了上面的变量。 注意!!! 如果你的项目中使用了webpack或其他打包工具,可以直接import,不用改变变量名好在这个xlsx.extendscript.js不是压缩版本,可以对内容进行修改,就把暴露出来的变量修改为’XLSX2’吧。这样我们只有在使用utils工具的时候才用到xlsx.extendscript.js,其余都用的是xlsx-style这个js,这样总该可以了吧 。 修改完之后别忘了将XSLX.utils.table_to_sheet()改成XLSX2.utils.table_to_sheet()。 (不建议修改源码,由于工作需要不修改源码无法使用才做的修改) function btn_export() { var table1 = document.querySelector("#table1"); var sheet = XLSX2.utils.table_to_sheet(table1); sheet["A5"].s = { font: { sz: 13, bold: true, color: { rgb: "FFFFAA00" } }, alignment: { horizontal: "center", vertical: "center", wrap_text: true } }; openDownloadDialog(sheet2blob(sheet), '下载.xlsx'); }运行: 可以看到,你所做的样式更改已经生效了。 客户需求增加:我想要前面几行空出来,并且写上打印公司名。 观察xlsx.extendscript.js源码,发现table_to_sheet,也就是parse_dom_table,并没有设置起始行的参数,下面给出parse_dom_table的代码: function parse_dom_table(table, _opts) { var opts = _opts || {}; if(DENSE != null) opts.dense = DENSE; var ws = opts.dense ? ([]) : ({}); var rows = table.getElementsByTagName('tr'); var sheetRows = opts.sheetRows || 10000000; var range = {s:{r:0,c:0},e:{r:0,c:0}}; var merges = [], midx = 0; var rowinfo = []; var _R = 0, R = 0, _C, C, RS, CS; for(; _R if (opts.display) continue; rowinfo[R] = {hidden: true}; } var elts = (row.children); for(_C = C = 0; _C var m = merges[midx]; if(m.s.c == C && m.s.r s:{r:R,c:C},e:{r:R + (RS||1) - 1, c:C + CS - 1}}); var o = {t:'s', v:v}; var _t = elt.getAttribute("t") || ""; if(v != null) { if(v.length == 0) o.t = _t || 'z'; else if(opts.raw || v.trim().length == 0 || _t == "s"){} else if(v === 'TRUE') o = {t:'b', v:true}; else if(v === 'FALSE') o = {t:'b', v:false}; else if(!isNaN(fuzzynum(v))) o = {t:'n', v:fuzzynum(v)}; else if(!isNaN(fuzzydate(v).getDate())) { o = ({t:'d', v:parseDate(v)}); if(!opts.cellDates) o = ({t:'n', v:datenum(o.v)}); o.z = opts.dateNF || SSF._table[14]; } } if(opts.dense) { if(!ws[R]) ws[R] = []; ws[R][C] = o; } else ws[encode_cell({c:C, r:R})] = o; if(range.e.c = sheetRows) ws['!fullref'] = encode_range((range.e.r = rows.length-_R+R-1,range)); // We can count the real number of rows to parse but we don't to improve the performance return ws; }那自己加一个吧 可以看到,里面的R变量 这是控制起始行的关键所在,好吧,我们再做一下修改: var _R = 0, R = _opts.rowIndex || 0, _C, C, RS, CS;这里我们给_opts增加一个属性rowIndex,在调用table_to_sheet方法的时候传入这个属性。下面是变更后的代码: function btn_export() { var table1 = document.querySelector("#table1"); var opt = { rowIndex: 4 }; //开头空4行 var sheet = XLSX2.utils.table_to_sheet(table1, opt); sheet["A1"] = { t: "s", v: '三鹿集团有限公司' }; //给A1单元格赋值 sheet["A1"].s = { font: { name: '宋体', sz: 24, bold: true, underline: true, color: { rgb: "FFFFAA00" } }, alignment: { horizontal: "center", vertical: "center", wrap_text: true }, fill: { bgColor: { rgb: 'ffff00' } } }; //["!merges"]这个属性是专门用来进行单元格合并的 sheet["!merges"].push({//如果不为空push 为空 = 赋值 //合并单元格 index都从0开始 s: { //s开始 c: 0, //开始列 r: 0 //开始行 }, e: { //e结束 c: 3, //结束列 r: 2 //结束行 } }); sheet["A9"].s = { //样式 font: { sz: 13, bold: true, color: { rgb: "FFFFAA00" } }, alignment: { horizontal: "center", vertical: "center", wrap_text: true } }; openDownloadDialog(sheet2blob(sheet), '下载.xlsx'); }运行结果: 客户又提新需求了,要加上2个字段,身份证号和手机号。 这还不简单?加上2个字段不就好了。2分钟搞定,导出: 意思是只要从td的text里读取到的值,只要转换之后是一个number,(不管你是string类型),都会给你来一个fuzzynum(v),转换成一个number类型。 做下修改,结果: function parse_dom_table(table, _opts) { var opts = _opts || {}; if(DENSE != null) opts.dense = DENSE; var ws = opts.dense ? ([]) : ({}); var rows = table.getElementsByTagName('tr'); var sheetRows = opts.sheetRows || 10000000; var range = {s:{r:0,c:0},e:{r:0,c:0}}; var merges = [], midx = 0; var rowinfo = []; var _R = 0, R = _opts.rowIndex || 0, _C, C, RS, CS; for(; _R if (opts.display) continue; rowinfo[R] = {hidden: true}; } var elts = (row.children); for(_C = C = 0; _C var m = merges[midx]; if(m.s.c == C && m.s.r s:{r:R,c:C},e:{r:R + (RS||1) - 1, c:C + CS - 1}}); var o = {t:'s', v:v}; var _t = elt.getAttribute("t") || ""; if(v != null) { if(v.length == 0) o.t = _t || 'z'; else if(opts.raw || v.trim().length == 0 || _t == "s"){} else if(v === 'TRUE') o = {t:'b', v:true}; else if(v === 'FALSE') o = {t:'b', v:false}; //else if(!isNaN(fuzzynum(v))) o = {t:'n', v:fuzzynum(v)}; else if(!isNaN(fuzzynum(v))) o = {t:'s', v:v};//不自动格式化number类型 else if(!isNaN(fuzzydate(v).getDate())) { o = ({t:'d', v:parseDate(v)}); if(!opts.cellDates) o = ({t:'n', v:datenum(o.v)}); o.z = opts.dateNF || SSF._table[14]; } } if(opts.dense) { if(!ws[R]) ws[R] = []; ws[R][C] = o; } else ws[encode_cell({c:C, r:R})] = o; if(range.e.c = sheetRows) ws['!fullref'] = encode_range((range.e.r = rows.length-_R+R-1,range)); // We can count the real number of rows to parse but we don't to improve the performance return ws; }将转换的语句注释掉,重写这行代码,如果是number类型,不做任何修改,该是什么值还是什么值。 现在再重新运行,结果: 注意,设置单元格列宽要从第一行开始设置 结果: csdn下载 完整实例 由于csdn积分制度递增,无法控制,所以贴上github地址 完整实例 总结 不是特殊情况不建议修改源码因为毕竟修改了代码,所以这种方法只能面向小众听过收费版功能很全,建议如果有需要的话还是购买收费版本,但是地址没找到…可以根据自己需求对xlsx源码进行修改,以便满足自己工作的需求。但是这样较难以维护,如何取舍还是自行斟酌。我这里只列取了我实际工作中所需要的功能,xlsx的功能很丰富,有空可以多琢磨琢磨。 |
CopyRight 2018-2019 实验室设备网 版权所有 |