前端使用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套高效原型设计框架模板全解析
中后台管理信息系统作为企业内部管理的核心支撑,其设计与实现对于提升企业的运营效率与决策能力具有至关重要的作用。为了满足多样化的中后台管理系统开发需求,一套全面、灵活的原型设计方案显得尤为重要。本文将深入探讨中后台管理信息系统通用原型方案…...
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造,完美适配AGV和无人叉车。同时,集成以太网与语音合成技术,为各类高级系统(如MES、调度系统、库位管理、立库等)提供高效便捷的语音交互体验。 L…...
【Python】 -- 趣味代码 - 小恐龙游戏
文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...
基于Flask实现的医疗保险欺诈识别监测模型
基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施,由雇主和个人按一定比例缴纳保险费,建立社会医疗保险基金,支付雇员医疗费用的一种医疗保险制度, 它是促进社会文明和进步的…...
聊聊 Pulsar:Producer 源码解析
一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台,以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中,Producer(生产者) 是连接客户端应用与消息队列的第一步。生产者…...
华为OD机试-食堂供餐-二分法
import java.util.Arrays; import java.util.Scanner;public class DemoTest3 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextIn…...
iOS性能调优实战:借助克魔(KeyMob)与常用工具深度洞察App瓶颈
在日常iOS开发过程中,性能问题往往是最令人头疼的一类Bug。尤其是在App上线前的压测阶段或是处理用户反馈的高发期,开发者往往需要面对卡顿、崩溃、能耗异常、日志混乱等一系列问题。这些问题表面上看似偶发,但背后往往隐藏着系统资源调度不当…...
基于SpringBoot在线拍卖系统的设计和实现
摘 要 随着社会的发展,社会的各行各业都在利用信息化时代的优势。计算机的优势和普及使得各种信息系统的开发成为必需。 在线拍卖系统,主要的模块包括管理员;首页、个人中心、用户管理、商品类型管理、拍卖商品管理、历史竞拍管理、竞拍订单…...
【Linux】Linux 系统默认的目录及作用说明
博主介绍:✌全网粉丝23W,CSDN博客专家、Java领域优质创作者,掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围:SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物…...
CSS | transition 和 transform的用处和区别
省流总结: transform用于变换/变形,transition是动画控制器 transform 用来对元素进行变形,常见的操作如下,它是立即生效的样式变形属性。 旋转 rotate(角度deg)、平移 translateX(像素px)、缩放 scale(倍数)、倾斜 skewX(角度…...
MyBatis中关于缓存的理解
MyBatis缓存 MyBatis系统当中默认定义两级缓存:一级缓存、二级缓存 默认情况下,只有一级缓存开启(sqlSession级别的缓存)二级缓存需要手动开启配置,需要局域namespace级别的缓存 一级缓存(本地缓存&#…...
