前端使用xlsx-js-style导出Excel,带样式,并处理合并单元格边框显示不全和动态插入表头解决
一、在学习之前,先给出一些学习/下载地址:
xlsx-js-style下载地址
https://github.com/gitbrent/xlsx-js-style
或者
https://www.npmjs.com/package/xlsx-js-style
SheetJS中文教程:
https://xlsx.nodejs.cn/docs/csf/cell
二、先看样式
页面HTML显示

2.1 导出带边框的表格Excel显示样式:

2.2 表格插入表头操作Excel显示样式

三、全部代码:
<html>
<head><script src="dist/xlsx.bundle.js"></script><style type="text/css">.tbexport {border-collapse: collapse;width: 500px;}.tbexport th, td {border: 1px solid #ddd;padding: 8px;text-align: left;}.tbexport2 {border-collapse: collapse;width: 100%;}.tbexport2 th, td {border: 1px solid #ddd;text-align: left;}</style><scriptsrc="https://code.jquery.com/jquery-3.7.1.min.js"integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo="crossorigin="anonymous"></script>
<!-- 如果这个jquery连接不上,可以自己下载一个--><head>
<body>
<table id="TableToExport" class="tbexport"><tr><td>序号</td><td>名称</td><td>测试1</td><td>测试2</td><td>测试3</td><td>测试4</td></tr><tr><td>1</td><td>bb</td><td>345</td><td>566</td><td>777</td><td>888</td></tr><tr><td>2</td><td>bb</td><td rowspan="3">999</td><td>566</td><td>777</td><td>888</td></tr><tr><td>3</td><td>bb</td><td>999</td><td>1010</td><td>111</td></tr><tr><td>4</td><td>bb</td><td>333</td><td>44</td><td>55</td></tr><tr><td colSpan="2">合计</td><td>22</td><td>77</td><td>88</td><td>99</td></tr>
</table><style type="text/css">.datatable{}.datatable td{padding:10px;border:1px solid #000}.datatable thead td {background-color:#f0f0f0}
</style><button id="sheetjsexport" onclick = "myExportExcel()"><b>合并单元格导出带边框</b></button><button onclick = "myExportExcel2()"><b>导出带表头表格</b></button>
<script>var MyStyle = {borderStyle:{border: {top: {style: 'thin',color: {auto: 1}},left: {style: 'thin',color: {auto: 1}},right: {style: 'thin',color: {auto: 1}},bottom: {style: 'thin',color: {auto: 1}}},},centerStyle: {alignment: {horizontal: "center",vertical: "center"}},leftStyle :{alignment: {horizontal: "left",vertical: "center"},},rightStyle : {alignment: {horizontal: "right",vertical: "center"},},boldStyle : { //设置一级标题样式font: {// sz: 12,bold: true,// color: {rgb: "000000"}}},smallStyle : { //设置一级标题样式font: {sz: 9,bold: false,color: {rgb: "222222"}}},titleStyle : { //设置一级标题样式font: {sz: 14,bold: true,// color: {rgb: "000000"}},alignment: {horizontal: "center",vertical: "center"},},title2Style : { //设置二级标题样式font: {bold: true,// color: {rgb: "000000"}},alignment: {horizontal: "center",vertical: "center"},},bgStyle : {fill:{fgColor: {rgb: "EEECE1"}},}
};function checkEmptyItem(ws ){var range = XLSX.utils.decode_range(ws['!ref']);
// // 计算最大列号var maxCol = range.e.c; // 'e' 代表结束列,'c' 是列号的字段var maxRow = range.e.r;//不加时,合并单元格边框会缺少for(let i = 0; i<=maxRow; i++){for(let j = 0;j<=maxCol; j++){if (ws[XLSX.utils.encode_cell({r: i, c: j})] == undefined) {ws[XLSX.utils.encode_cell({r: i, c: j})] ={t: 's', v: "", z: XLSX.utils.encode_cell({r: i, c: j})};}}}return ws;
}function myExportExcel()
{/* Create worksheet from HTML DOM TABLE */var wb = XLSX.utils.table_to_book(document.getElementById("TableToExport"),{sheet:'测试',raw:true})/* Export to file (start a download) */var ws = wb.Sheets["测试"]; // get the currentconst range = XLSX.utils.decode_range(ws['!ref']);
// // 计算最大列号const maxCol = range.e.c; // 'e' 代表结束列,'c' 是列号的字段const maxRow = range.e.r;let arr = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M","N","O","P"] //总共多少列//设置公共样式ws = checkEmptyItem(ws);for (let i = 1; i <= maxRow+1; i++) {for(j = 0;j<=maxCol; j++){var item = arr[j];let str = item + i;if (ws[str]) {var cellStyle = { };cellStyle = $.extend(cellStyle, MyStyle.borderStyle) ;cellStyle = $.extend(cellStyle, MyStyle.centerStyle) ;if(i==1){cellStyle = $.extend(cellStyle, MyStyle.title2Style) ;ws['!cols'][j]={wpx:120};//设置列的高度}}Object.assign(ws[str], {s: cellStyle});}ws['!rows'][i-1] = { hpx:30 };//设置行的高度}XLSX.writeFile(wb, "SheetJSTable.xlsx");
}
//导出带表头样式
function myExportExcel2() {/* Create worksheet from HTML DOM TABLE */var wb = XLSX.utils.table_to_book(document.getElementById("TableToExport"), {sheet: '测试',raw: true,origin: {c: 0, r: 1}}); //从第1列,第三行开始var ws = wb.Sheets["测试"]; // get the current// 要插入的新行数据const newRow = ['测试完成情况'];
//添加1行合并单元格内容var nMergeLength = ws["!merges"].length;ws["!merges"][nMergeLength] = XLSX.utils.decode_range("A1:F1");
// 表头设置值ws[XLSX.utils.encode_cell({r: 0, c: 0})] ={t: 's', v: newRow[0], z: XLSX.utils.encode_cell({r: 0, c: 0})};
//设置表头样式Object.assign(ws["A1"], {s: MyStyle.titleStyle});ws['!rows'][0] = {hpx: 50};const range = XLSX.utils.decode_range(ws['!ref']);
// // 计算最大列号const maxCol = range.e.c; // 'e' 代表结束列,'c' 是列号的字段const maxRow = range.e.r;let arr = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P"] //总共多少列ws = checkEmptyItem(ws);//设置公共样式for (let i = 2; i <= maxRow + 1; i++) {for (j = 0; j <= maxCol; j++) {var item = arr[j];let str = item + i;if (ws[str]) {var cellStyle = {};cellStyle = $.extend(cellStyle, MyStyle.borderStyle);cellStyle = $.extend(cellStyle, MyStyle.centerStyle);if (i == 2) {cellStyle = $.extend(cellStyle, MyStyle.title2Style, MyStyle.bgStyle);ws['!cols'][j] = {wpx: 120};//设置列的高度}}Object.assign(ws[str], {s: cellStyle});}ws['!rows'][i - 1] = {hpx: 30};//设置行的高度}XLSX.writeFile(wb, "SheetJSTable.xlsx");
}
</script>
===================================================</body></html>
四、关键代码说明:
4.1. 这里主要是为了合并单元格时,给空单元格设置一个空值,不然加边框时就不会显示
function checkEmptyItem(ws ){var range = XLSX.utils.decode_range(ws['!ref']);
// // 计算最大列号var maxCol = range.e.c; // 'e' 代表结束列,'c' 是列号的字段var maxRow = range.e.r;//不加时,合并单元格边框会缺少for(let i = 0; i<=maxRow; i++){for(let j = 0;j<=maxCol; j++){if (ws[XLSX.utils.encode_cell({r: i, c: j})] == undefined) {ws[XLSX.utils.encode_cell({r: i, c: j})] ={t: 's', v: "", z: XLSX.utils.encode_cell({r: i, c: j})};}}}return ws;
}
4.2 如果需要插入表头:
a) 加这句的意思是从第1行,第0列开始导出表格,意思就是给表头预留一行:
var wb = XLSX.utils.table_to_book(document.getElementById(“TableToExport”), {
sheet: '测试',
raw: true,
origin: {c: 0, r: 1}
});
b) 给表头设置值和加入样式:
//添加1行合并单元格内容
var nMergeLength = ws["!merges"].length;ws["!merges"][nMergeLength] = XLSX.utils.decode_range("A1:F1");
// 表头设置值
ws[XLSX.utils.encode_cell({r: 0, c: 0})] ={t: 's', v: newRow[0], z: XLSX.utils.encode_cell({r: 0, c: 0})};
//设置表头样式
Object.assign(ws["A1"], {s: MyStyle.titleStyle});ws['!rows'][0] = {hpx: 50};
下载地址:
https://download.csdn.net/download//89804082
相关文章:
前端使用xlsx-js-style导出Excel,带样式,并处理合并单元格边框显示不全和动态插入表头解决
一、在学习之前,先给出一些学习/下载地址: xlsx-js-style下载地址 https://github.com/gitbrent/xlsx-js-style 或者 https://www.npmjs.com/package/xlsx-js-style SheetJS中文教程: https://xlsx.nodejs.cn/docs/csf/cell 二、先看样…...
自动化工具ansible部署和实践
1 介绍和部署 1.1 介绍 ansible的功能 我爱你在当今的IT自动化领域,Ansible无疑是一个无法被忽视的重要角色。其便利性和高效性受到了广大开发者和系统管理员的一致好评,成为了配置管理和应用部署的首选工具。然而,对于一些初学者来说&#…...
无人机推流直播平台EasyDSS视频技术如何助力冬季森林防火
冬季天干物燥,大风天气频繁,是森林火灾的高发期。相比传统的人力巡查,无人机具有更高的灵敏度和准确性,尤其在夜间或浓雾天气中,依然能有效地监测潜在火源。 无人机可以提供高空视角和实时图像传输,帮助巡…...
React Fiber
React Fiber 是 React 16 引入的全新重写的协调(Reconciliation)算法的实现,旨在改善 React 的更新机制和性能,尤其是在复杂应用和大量更新的场景下。它使得 React 更加灵活、可调度,能够实现优先级控制和中断更新等特…...
【前端】JavaScript 中的 map() 方法:高级解析与应用
博客主页: [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: 前端 文章目录 💯前言💯map() 方法的定义与核心特性1.1 方法定义1.2 主要特性 💯map() 方法的语法与高级用法2.1 基本语法2.2 简化写法与箭头函数2.3 结合链式操作 💯ma…...
《智能体开发实战(高阶)》四、系统化的日志周报智能体开发计划
智能体扩展与完善规划 为了将前几个章节的智能体逐步扩展为支持整个公司团队使用的高效工具,以下是分阶段的完善与扩写规划。每个阶段旨在提升功能覆盖范围、处理能力和用户体验,并为企业提供实际价值。 阶段一:基础功能完善 目标:巩固现有功能,提升健壮性和适用性。 支…...
什么是Apache日志?为什么Apache日志分析很重要?
Apache是全球最受欢迎的Web服务器软件,支持约30.2%的所有活跃网站。凭借其可靠性、灵活性和强大的功能,Apache数十年来一直是互联网的中坚力量。 一、Apache Web服务器的工作原理 Apache Web服务器的工作原理如下: 接收HTTP请求࿱…...
Mybatis——(2)
2.2 Mybatis 工具类(了解) 为了简化MyBatis的开发,可将MyBatis进一步封装。 import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apa…...
景联文科技入选中国信通院发布的“人工智能数据标注产业图谱”
近日,由中国信息通信研究院、中国人工智能产业发展联盟牵头,联合中国电信集团、沈阳市数据局、保定高新区等70多家单位编制完成并发布《人工智能数据标注产业图谱》。景联文科技作为人工智能产业关键环节的代表企业,入选图谱中技术服务板块。…...
修改浏览器地址栏参数
Vue 修改当前页面地址栏参数 function updateUrlParameter(param: string, value: string) {const url new URL(window.location.href); // 获取当前页面的 URL// 解析哈希部分const hash url.hash ? url.hash.slice(1) : "";const [path, queryString] hash.sp…...
Spring Boot教程之二十五: 使用 Tomcat 部署项目
Spring Boot – 使用 Tomcat 部署项目 Spring Boot 是一个基于微服务的框架,在其中创建可用于生产的应用程序只需很少的时间。Spring Boot 建立在 Spring 之上,包含 Spring 的所有功能。如今,它正成为开发人员的最爱,因为它是一个…...
解决 Git 默认不区分文件名大小写的问题
不得不说 Git 默认不区分文件名大小写真是一个大坑,由于之前的项目目录比较乱,项目下的文件夹命名都不规范,这两天一直在整理,然后今天从服务器将项目重新 clone 下来后发现,之前将所有文件名首字母改成大写的改动全部…...
python学opencv|读取图像(十二)BGR图像转HSV图像
【1】引言 前述已经学习了opencv中图像BGR相关知识,文章链接包括且不限于下述: python学opencv|读取图像(六)读取图像像素RGB值_opencv读取灰度图-CSDN博客 python学opencv|读取图像(七)抓取像素数据顺利…...
信息安全工程师-选择题考点总结
密码理论知识 基础理论 一个密码系统至少由明文、密文、加密算法、解密算法和密钥五个部分组成,而其安全性是由密钥决定的。 按照密钥特征的不同,密码体制分为:对称密码体制和非对称密码体制。 按照对明文加密方式的不同,密码体制分为:流密码和分组密码。 非对称密码体…...
重学SpringBoot3-WebClient配置与使用详解
更多SpringBoot3内容请关注我的专栏:《SpringBoot3》 期待您的点赞👍收藏⭐评论✍ 重学SpringBoot3-WebClient配置与使用详解 1. 简介2. 环境准备2.1 依赖配置 3. WebClient配置3.1 基础配置3.2 高级配置3.3 retrieve()和exchange()区别 4. 使用示例4.1 …...
springBoot中的日志级别在哪里配置
在Spring Boot中,日志级别的配置可以通过多种方式来实现,主要包括在配置文件中设置、使用自定义的logback配置文件,以及在代码中动态配置等。以下是一些具体的配置方法: 一、在配置文件中设置日志级别 Spring Boot默认使用appli…...
统一身份安全管理体系的业务协同能力
随着集团企业数字化组织转型深化,各组织机构间业务协同程度提升。研发业务协同、数据驱动生产决策等数字化生产协作工作体系得以展开,企业内数据流转加快。企业对统一身份安全管理体系的业务协同管理和支撑能力要求提升: 统一身份管理流程需…...
JAVA课堂笔记23(IO流 (java.io包中))
第五章:IO流 (java.io包中) 三、字符流 1. 字符流的父类(抽象类): Reader:字符输入流 对应的操作为读操作 功能方法:read方法 Writer:字符输出流 对应的操作为写操作 功能方法:write方法 …...
C# DLT645 97/07数据采集工具
电表模拟器 97协议测试 07协议测试 private void btnSend_Click(object sender, EventArgs e) {string addr txtAddr.Text.Trim();string data txtDataFlg.Text.Trim();byte control 0x01;switch (cmbControl.SelectedIndex){case 0: control (byte)0x01; break;// 97协议c…...
中后台管理信息系统:Axure12套高效原型设计框架模板全解析
中后台管理信息系统作为企业内部管理的核心支撑,其设计与实现对于提升企业的运营效率与决策能力具有至关重要的作用。为了满足多样化的中后台管理系统开发需求,一套全面、灵活的原型设计方案显得尤为重要。本文将深入探讨中后台管理信息系统通用原型方案…...
浅谈 React Hooks
React Hooks 是 React 16.8 引入的一组 API,用于在函数组件中使用 state 和其他 React 特性(例如生命周期方法、context 等)。Hooks 通过简洁的函数接口,解决了状态与 UI 的高度解耦,通过函数式编程范式实现更灵活 Rea…...
rknn优化教程(二)
文章目录 1. 前述2. 三方库的封装2.1 xrepo中的库2.2 xrepo之外的库2.2.1 opencv2.2.2 rknnrt2.2.3 spdlog 3. rknn_engine库 1. 前述 OK,开始写第二篇的内容了。这篇博客主要能写一下: 如何给一些三方库按照xmake方式进行封装,供调用如何按…...
Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例
使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件,常用于在两个集合之间进行数据转移,如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model:绑定右侧列表的值&…...
Debian系统简介
目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版ÿ…...
Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)
目录 1.TCP的连接管理机制(1)三次握手①握手过程②对握手过程的理解 (2)四次挥手(3)握手和挥手的触发(4)状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...
dedecms 织梦自定义表单留言增加ajax验证码功能
增加ajax功能模块,用户不点击提交按钮,只要输入框失去焦点,就会提前提示验证码是否正确。 一,模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...
第 86 场周赛:矩阵中的幻方、钥匙和房间、将数组拆分成斐波那契序列、猜猜这个单词
Q1、[中等] 矩阵中的幻方 1、题目描述 3 x 3 的幻方是一个填充有 从 1 到 9 的不同数字的 3 x 3 矩阵,其中每行,每列以及两条对角线上的各数之和都相等。 给定一个由整数组成的row x col 的 grid,其中有多少个 3 3 的 “幻方” 子矩阵&am…...
今日学习:Spring线程池|并发修改异常|链路丢失|登录续期|VIP过期策略|数值类缓存
文章目录 优雅版线程池ThreadPoolTaskExecutor和ThreadPoolTaskExecutor的装饰器并发修改异常并发修改异常简介实现机制设计原因及意义 使用线程池造成的链路丢失问题线程池导致的链路丢失问题发生原因 常见解决方法更好的解决方法设计精妙之处 登录续期登录续期常见实现方式特…...
AI病理诊断七剑下天山,医疗未来触手可及
一、病理诊断困局:刀尖上的医学艺术 1.1 金标准背后的隐痛 病理诊断被誉为"诊断的诊断",医生需通过显微镜观察组织切片,在细胞迷宫中捕捉癌变信号。某省病理质控报告显示,基层医院误诊率达12%-15%,专家会诊…...
vulnyx Blogger writeup
信息收集 arp-scan nmap 获取userFlag 上web看看 一个默认的页面,gobuster扫一下目录 可以看到扫出的目录中得到了一个有价值的目录/wordpress,说明目标所使用的cms是wordpress,访问http://192.168.43.213/wordpress/然后查看源码能看到 这…...
