2000字范文,分享全网优秀范文,学习好帮手!
2000字范文 > layui 复杂表头多层表头的表格数据非后台导出excel

layui 复杂表头多层表头的表格数据非后台导出excel

时间:2021-08-23 13:34:18

相关推荐

layui 复杂表头多层表头的表格数据非后台导出excel

用过layui table的都了解,layui的表格自带导出功能,只要在属性toolbar里配置即可。

如果嫌toolbar里的导出按钮不够美观,layui也友好的提供了自行定义按钮后调用导出页面数据的方法,详见:官方文档

遗憾的是:该方法暂时并不支持对多层表头的导出。

而多层复杂表头在很多系统中都有体现,而若不想通过后台代码去做导出,只在前端页面上该如何做呢?

目录&历程

1 史前1.1 直接使用(两种方式)1.2 上述插件使用场景解析1.3 不可用场景处理1.4 处理后的使用1.5 新的情况兼容:固定列2 蜕变2.1 table2excel_ext.js的诞生2.2 新的情况兼容:合计行2.3 新的情况兼容:排除列

1 史前

1.1 直接使用(两种方式)

1.下载插件:

地址:github table2excel

下载下来项目后,在项目的dist中就有该js,在自己表格html页面引用即可使用。

链接:百度云下载js

提取码:1f52

/*** 使用方法该js的方法(两行代码)*/let table2excel = new Table2Excel();// 传入你的tableId即可导出table2excel.export($('#tableId'), "your filename");

一个解析页面元素方法:复制走即可使用

/*** * @param id:表格的id* @param fileName:导出的excel的名字*/function exportForExcle(id,fileName){var table = $(document.getElementById(id)).clone();table.attr('id','datatab');table.appendTo('body');method5('datatab');datatab.remove();function method5(tableid) {var idTmr;var tableToExcel = (function() {var uri = 'data:application/vnd.ms-excel;base64,',template = '<html><head><meta charset="UTF-8"></head><body><table border="1px">{table}</table></body></html>',base64 = function(s) {return window.btoa(unescape(encodeURIComponent(s))) },format = function(s, c) {return s.replace(/{(\w+)}/g, function(m, p) {return c[p]; }) }return function(table, name) {if (!table.nodeType) table = document.getElementById(table)var ctx = {worksheet: name || 'Worksheet', table: table.innerHTML}var aTag = document.createElement('a');aTag.download = fileName;aTag.href = uri + base64(format(template, ctx));document.body.appendChild(aTag);aTag.onclick = function () {document.body.removeChild(aTag);}aTag.click();}})()if(getExplorer()=='ie'){var curTbl = document.getElementById(tableid);var oXL = new ActiveXObject("Excel.Application");var oWB = oXL.Workbooks.Add();var xlsheet = oWB.Worksheets(1);var sel = document.body.createTextRange();sel.moveToElementText(curTbl);sel.select();sel.execCommand("Copy");xlsheet.Paste();oXL.Visible = true;try {var fname = oXL.Application.GetSaveAsFilename("Excel.xls", "Excel Spreadsheets (*.xls), *.xls");} catch (e) {print("Nested catch caught " + e);} finally {oWB.SaveAs(fname);oWB.Close(savechanges = false);oXL.Quit();oXL = null;idTmr = window.setInterval("Cleanup();", 1);}}else{tableToExcel(tableid)}function Cleanup() {window.clearInterval(idTmr);CollectGarbage();}function getExplorer() {var explorer = window.navigator.userAgent ;//ieif (explorer.indexOf("MSIE") >= 0) {return 'ie';}//firefoxelse if (explorer.indexOf("Firefox") >= 0) {return 'Firefox';}//Chromeelse if(explorer.indexOf("Chrome") >= 0){return 'Chrome';}//Operaelse if(explorer.indexOf("Opera") >= 0){return 'Opera';}//Safarielse if(explorer.indexOf("Safari") >= 0){return 'Safari';}}}}

1.2 上述插件使用场景解析

可用的情况:表格的渲染方式为静态渲染,即在html的table标签中渲染好了表头与数据。

不可用的情况:表格的渲染方式为动态渲染,即从后台查询数据来渲染表格,包括渲染动态的表头。

不可用的情况原因:用layui.table动态渲染的表格,不会在页面的html table标签中添加doom元素。

如下图的表格(表头和数据均为动态渲染),layui渲染数据后,并不会在table标签中append doom元素,而是会在table 标签的下面追加一个新的div,将tr th td 和数据全部存放在里面。

这也就导致了上述的两种方法均无法下载excel,就是因为:该插件在页面上找不到插件所需的doom节点与数据。

1.3 不可用场景处理

在表格渲染完成后的done方法中,去遍历页面上layui生成的div,抓取里面的格式与数据,来手动append到table中,再控制该table隐藏,来为导出做准备。

分析doom元素:能清晰看到表头和body的doom结构,里面有你需要的所有信息,包括表头的各种合并操作。 手动向table标签里append html。

table.render({...done: function (res, curr, count) {let header_tr = $("#tableId").next().find(".layui-table-header").find("tr");let body_tr = $("#tableId").next().find(".layui-table-body").find("tr");let header_html = "";let body_html = "";// 获取表头html,包括单元格的合并$.each(header_tr,function (i,tr) {let header_th = $(tr).find("th");header_html += "<tr>";$.each(header_th,function (j,th) {let rowspan_num = $(th).attr("rowspan");// 行合并数let colspan_num = $(th).attr("colspan");// 列合并数if (rowspan_num && !colspan_num){// 只有行合并时header_html += '<th rowspan= "'+ rowspan_num +'">';} else if (colspan_num && !rowspan_num){// 只有列合并时header_html += '<th colspan= "'+ colspan_num +'">';} else if (rowspan_num && colspan_num){// 行列合并均有时header_html += '<th rowspan= "'+ rowspan_num +'" colspan="'+ colspan_num +'">';} else {// 没有发生单元格合并header_html += '<th>';}header_html += $(th).children().children().text() + '</th>';// 获取表头名称并拼接th标签})header_html += '</tr>';})// 获取表格body数据$.each(body_tr,function (i,tr) {let body_td = $(tr).find("td");body_html += '<tr>';$.each(body_td,function (j,td) {body_html += '<td>' + $(td).children().text() + '</td>';})body_html += '</tr>';})$("#tableId tr").remove();// 清除之前的doom结构$("#tableId").append(header_html).append(body_html);$("#tableId").hide();}});

如果把最后hide()方法去掉,可以看到表格doom元素已经添加到table标签中。

1.4 处理后的使用

做了上面的处理后,就可使用第一步的方法做导出了

下面是导出方法和导出后的截图

导出的时候需要做一点小小的处理:

let table2excel = new Table2Excel();/*** 此处的show()是为了避免table2excel将hide属性带入excel中* 导致下载后的excel中所有数据被隐藏*/$('#tableId').show();table2excel.export($('#tableId'), "your filename");$('#tableId').hide();

说明:

1、上面在导出的时候如果不先把表格show显示出来。wps的excel会正常显示,而office的excel则会把所有数据隐藏。这也是这个插件强大的地方,属性也会copy到excel中去。

2、可能有的同学会觉得在这里显示出来自己添加的表格doom元素,会在页面上有一闪而过的视觉效果,亲测过,并没有。可能在网速超级卡顿的时候会出现。

3、当然,这并不是最佳的解决方法。欢迎讨论。

----------------------------------------------我是分割线------------------------------------------------

更新时间:10月17日 10点00分

感谢:@weixin_40915415 同学提出的固定列的特殊情况

1.5 新的情况兼容:固定列

layui在处理固定列时候的doom渲染跟活动列是不同的

如下所示:我们将第一列承揽组固定,再用之前版本的js去append html时会发现,固定列的header和body发生了重复(两次)

分析doom元素:

我们看到这里出现了两个header

原来layui在渲染有固定列的表头时,会把固定列的header和body再多渲染一次,放到样式为layui-table-fixeddiv里。

知道这种结构,我们就好做新的处理了。

新的获取header和body doom元素的js更改如下以兼容有固定列的layui table:

let header_tr = $($("#tableId").next().find(".layui-table-header")[0]).find("tr");let body_tr = $($("#tableId").next().find(".layui-table-body")[0]).find("tr");

----------------------------------------------我是分割线------------------------------------------------

2 蜕变

2.1 table2excel_ext.js的诞生

更新时间:07月28日

💕能耐心看到这儿的同学真的是爱学习的好同学,不过这儿我也给你准备了惊喜(本来觉得上面的那些是不是可以删掉了,后来一想也是自己当初的一个思路历程,就先留着吧)💕

笔者将上诉的相关操作抽出了两个方法appendexportLayTable添加到了table2excel.js中,直接将该修改后的js引入到需导出excel数据的页面使用即可。

链接:百度云下载 table2excel_ext.js

提取码:4lsc

使用方法:

var table2Excel ;table.render({elem: '#tableId',...done: function (res, curr, count) {table2Excel = new Table2Excel();table2Excel.append($("#tableId"));}) });// 导出excel点击事件$('#exportElemId').click(function(){let fileName = 'XXX-2028';table2Excel.exportLayTable($('#tableId'),fileName);});

----------------------------------------------我是分割线------------------------------------------------

2.2 新的情况兼容:合计行

更新时间:10月16日

感谢:@zhang_pengpeng 同学提出的合计行的情况

layui table 自动在前端计算添加的合计行(关于怎么开启合计行,请自行查看layui 官网文档)会在body的下面重新渲染一段新的dom结构。如下图所示:

针对此种情况,笔者已经将table2excel_ext.js做了新的兼容,请返回目录2.1进行下载使用即可。

----------------------------------------------我是分割线------------------------------------------------

2.3 新的情况兼容:排除列

更新时间:11月25日

感谢:@qq_26097713 同学提出的排除列(列表中一些不想被导出的列)的情况。

对于表格中的操作列,或者一些隐藏的列,又或者是一些不想导出的列。笔者对table2excel_ext.js做了新的兼容,来处理这种情况,下面将给出示例代码。

ps:引入新的js不会对以前的调用产生任何影响。

var table2Excel ;table.render({elem: '#tableId',...done: function (res, curr, count) {// 排除掉的列的field数组(此参数可以不传,默认导出所有列)let exceptColumns = ["field1","field2"];table2Excel = new Table2Excel();table2Excel.append($("#tableId"), exceptColumns);}) });

说明:

table2Excel.append(table,exceptColumns)方法中的第二个参数exceptColumns可以不传,不传表示导出所有列。其中exceptColumns数组中的值对应为渲染表格列时的field的值(表格中的操作列也请添加上一个field值,用于定位),如下:

...{title : "姓名",field : "username",// 此处的fieldwidth : "10",align : "center"}...

js下载链接已做更新,请返回目录2.1进行下载。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。