使用excel.js(layui-excel)进行layui多级表头导出,根据单元格内容设置背景颜色,并将导出函数添加到toolbar

本段是菜狗子的碎碎念,解决办法请直接从第二段开始看。layui多级表头的导出,弄了两天才搞定,中途一度想放弃,还好坚持下来了。一开始用的是layui的toolbar里自带的那个导出,但是多级表头没有正常导出,单元格背景颜色也没有。后来分别用了sheetjs和table2excel,导出的文件有大小,但是用wps打不开,或者打开空白,或者报错Uncaught TypeError: Cannot read property 'length' of undefined。最后用了excel.js,或者叫layui-excel,成功。导出样式如下:

excel.js下载地址:https://gitcode.com/gh_mirrors/la/layui-excel/overview?utm_source=csdn_github_accelerator&isLogin=1

1. 添加引用

excel.js在layui-excel-master\layui_exts\中,可以将文件夹layui_exts复制到工程代码的js\lay-module\中,然后在js\lay-config.js中添加layui自定义扩展excel,最后在html文件中引用。

window.rootPath = (function(src) {
	src = document.scripts[document.scripts.length - 1].src;
	return src.substring(0, src.lastIndexOf("/") + 1);
})();

layui.config({
	base: rootPath + "lay-module/",
	version: true
}).extend({
	excel: 'layui_exts/excel', //  后端接口封装
});
<script src="../../js/lay-config.js?v=2.0.0" charset="utf-8"></script>

2. 做表

layui.use(['form', 'table', 'myHttp','util', 'excel'], function () {
			var $ = layui.jquery,
				form = layui.form,
				table = layui.table,
				myHttp = layui.myHttp,
				util = layui.util,
				excel = layui.excel;

			cxUrl = myHttp.getDataList //此处获取表格展示的具体数据,要替换成你自己的数据接口
			table.render({
				elem: '#cxTable',
				url: cxUrl,
				toolbar: '#cxDTableToolbar',
				defaultToolbar: ['filter', 'exports', 'print'],
				cols: [
					[
						{
							field: 'id',
							title: '设备编号',
							width: 100,
							fixed: 'left',
							rowspan: 2,
							sort: true
						},
						{
							field: 'address',
							title: '设备地址',
							width: 240,
							rowspan: 2,
							sort: true
						},
						{
							width: 120,
							title: '1号传感器',
							align: 'center',
							colspan: 2
						},
						{
							width: 120,
							title: '2号传感器',
							align: 'center',
							colspan: 2
						}
					],
					[
						{
							field: 'device1value',
							width: 90,
							title: '数值'
						},
						{
							field: 'device1sts',
							width: 90,
							title: '状态',
							templet: function (d) {
                                //根据传感器的状态,设置背景颜色
								if (d.device1sts !== null && d.device1sts != '正常') {
									return '<div style="background-color: yellow;">' + d.device1sts + '</div>';
								} else {
									if (d.device1sts === null) {
										d.device1sts = '';
									}
									return d.device1sts;
								}
							}
						},
						{
							field: 'device2value',
							width: 90,
							title: '数值'
						},
						{
							field: 'device2sts',
							width: 90,
							title: '状态',
							templet: function (d) {
								if (d.device2sts !== null && d.device2sts != '正常') {
								    return '<div style="background-color: yellow;">' + d.device2sts + '</div>';
								} else {
									if (d.device2sts === null) {
										d.device2sts = '';
									}
									return d.device2sts;
								}
							}
						}
					]
				],
				limits: [10, 25, 50, 100],
				limit: 10,
				page: true,
				skin: 'line'
			});

		});

3.导出

参考了https://blog.csdn.net/qq_42455262/article/details/128049644中的function exportFile()部分,我根据自己的情况,在其中增加引用了excel.setExportCellStyle(),作用是用黄色背景突出显示状态异常的器件,如果不需要,可以删掉。

<!-- 添加导出按钮 -->
<button id="exportButton">导出表格</button>
// 点击导出按钮,导出表格数据
$('#exportButton').click(function () {
				exportFile();
			});

function exportFile() {
				var bodys = $("div[class='layui-form layui-border-box layui-table-view'] .layui-table-box table").get(1); // 获取数据
				var btrs = Array.from(bodys.querySelectorAll("tr"))
				var btdslength = Array.from(btrs[0].querySelectorAll("td")).length;
				var headers = $("div[class='layui-form layui-border-box layui-table-view'] .layui-table-box table").get(0); // 获取表头
				var headerHead = $("div[class='layui-form layui-border-box layui-table-view'] .layui-table-box table thead").get(0); // 获取表头
				var htrs = Array.from(headers.querySelectorAll('tr'));

				var bodysArr = new Array();
				var point = new Array();  // 行,列
				for (var pi = 0; pi <= htrs.length + 1; pi++) {
					point[pi] = new Array();
				}
				point[0][0] = "qd"; // 起点
				var mergeArr = [];
				for (var j = 0; j < htrs.length; j++) {    // 遍历tr
					var titles = [];
					var hths = Array.from(htrs[j].querySelectorAll("th"));
					var titleAll = {};
					var pointIndex = 0;
					var pindx = 0;  // 起点遍历位置
					for (var i = 0; i < hths.length; i++) {  // 遍历 th
						var clazz = hths[i].getAttributeNode('class');
						var colspan = hths[i].getAttributeNode('colspan'); // 表头占用列数
						var rowspan = hths[i].getAttributeNode('rowspan'); //,表头占用行数
						if (!colspan) {
							colspan = 1;
						} else {
							colspan = parseInt(colspan.value);
						}
						if (!rowspan) {
							rowspan = 1;
						} else {
							rowspan = parseInt(rowspan.value);
						}
						// 判断数据起始填写位置
						for (; pindx < btdslength; pindx++) {
							if (j == 0 || point[j][pindx] == "qd") {
								titles.push(hths[i].innerText);
								for (var temp = 0; temp < colspan - 1; temp++) {
									titles.push(null);
								}
								mergeArr.push({ s: { r: j, c: pindx }, e: { r: j + rowspan - 1, c: pindx + colspan - 1 } }); // 添加合并数据参数  r的差R表示向下扩展R个单元格,c 的差C表示想右扩展C个单元格
								for (var qdi = 0; qdi < colspan; qdi++) {
									point[j + rowspan][pindx + qdi] = "qd"; // 添加完数据 ,添加起点记录
								}
								pindx = pindx + colspan;
								break;
							} else {
								titles.push(""); // 不能为null, 为null 会影响表格样式的设置
							}
						}
					}
					bodysArr.push(titles);
				}
				var widthArr = []; //这里改宽
				for (var j = 0; j < btrs.length; j++) {
					var contents = [];
					var btds = Array.from(btrs[j].querySelectorAll("td"));
					for (var i = 0; i < btds.length; i++) {
						contents.push(btds[i].innerText);
						if (j == 0) {  //只跑一圈
							widthArr.push({ wpx: btds[i].scrollWidth });
						}
					}
					bodysArr.push(contents)
				}

				//设置表格样式
				var styleStr = {
					alignment: {
						vertical: 'center',
						horizontal: 'center'
					},
					font: {
						sz: 14,
						// bold:true
					},
					border: {
						top: {
							style: 'thin'
						},
						bottom: {
							style: 'thin'
						},
						left: {
							style: 'thin'
						},
						right: {
							style: 'thin'
						}
					}
				}
				var datas = [];
				for (var i = 0; i < bodysArr.length; i++) {
					var map = {};
					var thisData = bodysArr[i];
					for (var n = 0; n < thisData.length; n++) {
						var dataName = "data_" + n;
						var das = thisData[n];
						var styMap = {};
						styMap['s'] = styleStr;
						styMap['v'] = das;
						map[dataName] = styMap;
					}
					datas.push(map);
				}
				
				var excel = layui.excel;
				// 开始填充单元格背景颜色
				// console.log(datas);
				excel.setExportCellStyle(
				    datas, 'D1:Q300',{
					s: {
						fill: { bgColor: { indexed: 64 }, fgColor: { rgb: "FFFF00" } },
						alignment: {
							horizontal: 'center',
							vertical: 'center'
						}
					}
				}, function (cell, newCell, row, config, currentRow, currentCol, fieldKey) {
					// 回调参数,cell:原有数据,newCell:根据批量设置规则自动生成的样式,row:所在行数据,config:传入的配置,currentRow:当前行索引,currentCol:当前列索引,fieldKey:当前字段索引
					// return ((currentRow + currentCol) % 2 === 0) ? newCell : cell;// 隔行隔列上色
					// console.log(cell['v']);
					if(cell['v'] == "疑似故障" || cell['v'] == "超上限值"){
						return newCell;
					}else{
						return cell;
					}
				})
				// console.log(data);
				// 结束填充单元格背景颜色

				var filename = "deviceSts.xlsx";

				// 第一行行高40,其余行默认20
				var rowConf = excel.makeRowConfig({
					1: 40
				}, 20)
				excel.exportExcel({
					sheet: datas
				}, filename, 'xlsx', {
					extend: {
						sheet: {
							'!merges': mergeArr
							, '!cols': widthArr
							, '!rows': rowConf
						}
					}
				})

			}

点击导出按钮,即可下载表格。到这里,layui复杂表头的导出已经实现,关于excel.js的详细使用,可以参考https://excel.wj2015.com/_book/,里面提供了功能演示和导出函数的使用介绍。

4.把导出函数添加到toolbar

这一步是为了美观,把导出函数添加到表格的toolbar,可以不做。下方代码片段中的'exports'对应的是默认导出菜单,{title: '下载',layEvent: 'LAYTABLE_EXPORT2',icon: 'layui-icon-export'}是新增的自定义导出菜单。

defaultToolbar: ['filter', 'exports', 'print', // 此处的'exports'对应的是默认的导出方式
                {
					title: '下载',
					layEvent: 'LAYTABLE_EXPORT2',
					icon: 'layui-icon-export'
				}, // 自定义导出函数接入
                {
					title: '提示',
					layEvent: 'LAYTABLE_TIPS',
					icon: 'layui-icon-tips'
				}],
//   监听添加操作,自定义导出,cxTable需要替换成你自己的table id
table.on('toolbar(cxTable)', function(obj) {
				if (obj.event === 'LAYTABLE_EXPORT2') { 
					// console.log('导出');
					exportFile();
				};
			});

此时,表格的右上角变成了5个菜单。如下图所示,第2个是默认导出,第4个是自定义导出,可以分别导出,对比一下导出效果。没什么问题的话,可以删除第2个菜单,即'export',只保留自定义导出菜单即可。

关于layui的更多教程,可以参考 layui开始使用_layui开始使用文档_layer在线开始使用文档_layui教程官网

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/898584.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ORACLE SELECT INTO 赋值为空,抛出 NO DATA FOUND 异常

例子&#xff1a; DECLARE ORDER_NUM VARCHAR2(20); BEGIN SELECT S.ORDER_NUM INTO ORDER_NUM FROM SALES_ORDER S WHERE S.ID122344; DBMS_OUTPUT.PUT_LINE(单号: || ORDER_NUM); END; 在查询结果为空的情况下&#xff0c;以上代码会报错&#xff1a;未找到任何数据 解决方…

深度学习——循环神经网络RNN知识点小结(全)

前置知识: 序列模型--输出/输入中包含有序列数据的模型 特点: 1.输入/输出元素之间具有顺序关系, 不同顺序得到的结果不同 2.输入输出不定长, 比如问答系统, 聊天机器人 DL--RNN 小名:循环神经网络 外国小名: sequence model 定义: 专门设计用来处理序列数据的神经网络 应用: …

2024临床常用的营养评价量表汇总!

临床常用量表来评估患者的营养状况、营养摄入风险&#xff0c;常笑医学整理了5个临床常用的营养评价量表&#xff0c;包括SGA营养评价表、老年营养风险指数、营养风险筛查评分简表、简易营养评价精法量表、微型营养评估量表等。这些量表在常笑医学网均支持在线评估、下载和创建…

(四)问题记录:matlab中spatial contact force模块下关于stiffness(刚度)的设定

最近在搞一阶倒立摆&#xff0c;在matlab仿真时遇到这样的问题&#xff1a;stiffness设置为10e5就会发生碰撞后穿透&#xff0c;&#xff08;四个spatial contact force模块是分别连接小车四个轮子和地面的&#xff09; 而设置成10e6就不会有问题&#xff0c; 由于本人也是第一…

cefsharp 88.2.90.0(Chromium 88.0.4324.182)支持H264视频播放-PDF预览 老版本回顾系列体验-100以下版本

一、关于此版本 Cef 88.2.9/CefSharp 88.2.90/Chromium 88.0.4324.182/支持H264/支持PDF预览 支持PDF预览和H264推荐版本 63/79/84/88/100/111/125 框架:NET4.5.2,X86 注意运行环境支持变化1.1 扩展(关于DPI黑边框问题解决) this.AutoScaleMode = AutoScaleMode.Dpi;

QT 机器视觉 1.相机类型

本专栏从实际需求场景出发详细还原、分别介绍大型工业化场景、专业实验室场景、自动化生产线场景、各种视觉检测物体场景介绍本专栏应用场景 更适合涉及到视觉相关工作者、包括但不限于一线操作人员、现场实施人员、项目相关维护人员&#xff0c;希望了解2D、3D相机视觉相关操作…

动态链接过程分析

目录 一、前言二、示例程序三、动态库的加载过程1、动态链接器加载动态库2、动态库的加载地址 四、符号重定位1、全局符号表2、全局偏移表 GOT3、liba.so 动态库文件的布局4、liba.so 动态库的虚拟地址5、GOT 表的内部结构6、反汇编 liba.so 代码 五、补充1、延迟绑定 plt 上文…

机器学习实战:从数据预处理到模型评估的完整案例

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…

面试总结一

面试总结 1、自我介绍一下自己2.面试11、css常用布局有哪些2、css常用的属性3.js原型链4、开发中遇到的技术难点5、闭包6、ts了解什么呢7.git都用什么命令8、vue怎么打包9.vue启动一个项目需要什么10、vue怎么创建一个项目 2.面试21.vue2和vue3有什么区别2.复杂组件的封装&…

《Java与API的浪漫邂逅:一键获取商品详情》

亲爱的Java爱好者们&#xff0c;你是否曾在夜深人静时&#xff0c;对着电脑屏幕发呆&#xff0c;思考如何用你的代码去征服那些遥远的API数据&#xff1f;你是否梦想着&#xff0c;只需轻轻一点&#xff0c;就能让商品详情如魔法般出现在你的眼前&#xff1f;今天&#xff0c;我…

数据结构与算法:贪心算法与应用场景

目录 11.1 贪心算法的原理 11.2 经典贪心问题 11.3 贪心算法在图中的应用 11.4 贪心算法的优化与扩展 总结 数据结构与算法&#xff1a;贪心算法与应用场景 贪心算法是一种通过选择当前最佳解来构造整体最优解的算法策略。贪心算法在很多实际问题中都取得了良好的效果&am…

Struts2标签库全解密:打造高效、动态的Web界面

文章目录 Struts2的标签通用(Generic)标签<s:property> 数据类标签<s:iterator>&#xff08;至关重要&#xff01;&#xff01;&#xff01;&#xff01;&#xff09;<s:if> <s:elseif> <s:else><s:a>超链接标签用户界面(UI)标签表单标签 …

【C++打怪之路Lv12】-- 模板进阶

#1024程序员节&#xff5c;征文# &#x1f308; 个人主页&#xff1a;白子寰 &#x1f525; 分类专栏&#xff1a;重生之我在学Linux&#xff0c;C打怪之路&#xff0c;python从入门到精通&#xff0c;数据结构&#xff0c;C语言&#xff0c;C语言题集&#x1f448; 希望得到您…

Java集合剖析4】LinkedList

目录 一、LinkedList的特有方法 二、LinkedList的底层数据结构 三、插入方法的具体实现 一、LinkedList的特有方法 LinkedList的底层是双向链表&#xff0c;它提供了操作首尾结点的方法。 二、LinkedList的底层数据结构 LinkedList的底层数据结构是一个双向链表&#xff0c;体现…

LeetCode 0908.最小差值 I:思维(遍历)

【LetMeFly】908.最小差值 I&#xff1a;思维&#xff08;遍历&#xff09; 力扣题目链接&#xff1a;https://leetcode.cn/problems/smallest-range-i/ 给你一个整数数组 nums&#xff0c;和一个整数 k 。 在一个操作中&#xff0c;您可以选择 0 < i < nums.length 的…

STM32:GPIO

目录 一、简介 二、结构 三、功能 1.GPIO 2.外部中断 四、示例 一、简介 输入输出&#xff08;IO&#xff09;是单片机最基本的外设功能之一。根据型号不同&#xff0c;STM32的IO端口数量不同&#xff0c;如64引脚的STM32F103RBT6有A、B、C、D四个IO端口&#xff0c;每个端…

追寻数组的轨迹,解开算法的情愫

公主请阅 1. 移除元素1.1 题目说明示例 1示例 2 1.2 题目分析1.3 代码部分1.4 代码分析 2. 删除有序数组中的重复项2.1 题目说明示例 1示例 3 2.2 题目分析2.3 代码部分2.4 代码分析 1. 移除元素 题目传送门 1.1 题目说明 题目描述&#xff1a; 给你一个数组 nums 和一个值 v…

代码随想录算法训练营第46期Day42

leetcode.518.零钱兑换 class Solution { public: //求装满背包有几种方法&#xff0c;公式都是&#xff1a;dp[j] dp[j - nums[i]]; // 如果求组合数就是外层for循环遍历物品&#xff0c;内层for遍历背包。 // 如果求排列数就是外层for遍历背包&#xff0c;内层for循环遍历物…

数据结构修炼——常见的排序算法:插入/希尔/选择/堆排/冒泡/快排/归并/计数

目录 一、常见的排序算法二、常见排序算法的实现2.1 排序算法回顾2.1.1 冒泡排序2.1.2 堆排序 2.2 直接插入排序2.3 希尔排序2.4 选择排序2.5 快速排序2.5.1 快速排序&#xff08;霍尔法&#xff09;2.5.2 快速排序&#xff08;挖坑法&#xff09;2.5.3 快速排序&#xff08;前…

Java实现html填充导出pdf

Java实现html填充导出pdf 1.依赖添加和pom修改 <!-- Thymeleaf 模板引擎 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><!-- OpenPDF 库 -…