前端使用xlsx-js-style导出Excel,带样式,并处理合并单元格边框显示不全和动态插入表头解决

news2024/9/30 0:06:02

一、在学习之前,先给出一些学习/下载地址:

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>
    <script
            src="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 current
    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 = 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};

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

双指针---(部分地更新)

双指针 复写零 给你一个长度固定的整数数组 arr &#xff0c;请你将该数组中出现的每个零都复写一遍&#xff0c;并将其余的元素向右平移。 注意&#xff1a;请不要在超过该数组长度的位置写入元素。请对输入的数组 就地 进行上述修改&#xff0c;不要从函数返回任何东西。 …

Tableau 瀑布图应用示例

通过探索 10 个示例&#xff0c;将瀑布图的应用拓展到更深层次的业务分析&#xff01; 作为一种直观展示数据变化的图表&#xff0c;瀑布图被广泛应用在业务分析中。同时&#xff0c;借助 Tableau 2024.2 中的 Viz Extensions&#xff0c;如今我们可以快速在 Tableau 中实现瀑布…

Vue3-TS-Lodash:理解Lodash / 常用方法积累

一、Lodash官网 Lodash 简介 | Lodash中文文档 | Lodash中文网 二、理解Lodash Lodash 是一个一致性、模块化、高性能的 JavaScript 实用工具库。它提供了大量的函数来帮助你处理数组、数值、对象、字符串等&#xff0c;使你的代码更加简洁、易读和高效。Lodash 的设计哲学是…

25基于python的文本冒险岛游戏(源码+游戏简介+python代码学习攻略)校园招聘面试

基于python的文本冒险岛游戏&#xff08;源代码游戏简介python代码学习&#xff09;资源-CSDN文库https://download.csdn.net/download/m0_72216164/89817518 开头附上工作招聘面试必备问题噢~~包括综合面试题、无领导小组面试题资源文件免费&#xff01;全文干货。 工作招聘无…

HarmoneyOS--Ability(能力)、窗口、通知

标题 文章目录 一、什么是Ability?二、使用步骤(单例和多例)三、窗口四、通知 一、什么是Ability? 开发模式提供的开发功能抽象的描述。 其中重要的是UiAbility,界面组件能力,负责所有界面的处理。 通过配置可以变更单例,多例,指定实例,在module.json5中进行配置 如: 单例:l…

FreeRTOS的中断管理

前言 FreeRTOS的任务有优先级&#xff0c;MCU的硬件中断有中断优先级&#xff0c;这是两个不同的概念&#xff0c;FreeRTOS的任务管理要用到硬件中断&#xff0c;使用FreeRTOS时候也可以使用硬件中断&#xff0c;但是硬件中断ISR的设计要注意一些设计原则&#xff0c;在本节中我…

RVC变声器入门

主要参考资料&#xff1a; RVC变声器官方教程&#xff1a;10分钟克隆你的声音&#xff01;一键训练&#xff0c;低配显卡用户福音&#xff01;: https://www.bilibili.com/video/BV1pm4y1z7Gm/?spm_id_from333.337.search-card.all.click&vd_sourcedd284033cd0c4d1f3f59a2…

RocketMQ消息发送之广播模式

前言 在前面的文章中我们回顾了RocketMQ的顺序消息和乱序消息&#xff0c;以及里面包含的乱序消息和全局消息&#xff0c;RocketMQ支持多种消息类型和消费模式 今天这篇文章主要介绍RocketMQ的广播消息。希望文章能为正在学习RocketMQ相关知识的大佬们提供帮助&#xff01; 广…

全自动ai生成视频MoneyPrinterTurbo源码 在线ai生成视频源码

介绍&#xff1a; 现在短视频这么火爆&#xff0c;流量就是金钱。 如果能全自动的生成短视频&#xff0c;是不是很容易带来流量&#xff0c;赚到马内。 MoneyPrinter 这个开源项目就可以自动生成短视频&#xff0c;而且质量还不错&#xff0c;不是那种低质的营销视频。 使用…

画个心,写个花!Python Turtle库带你玩转创意绘图!

文章目录 前言一、Turtle 库基础介绍二、画布设置三、画笔属性设置1.画笔颜色设置2.画笔粗细与速度设置3.画笔形状设置 四、画笔移动函数五、画笔控制函数六、实战案例一&#xff1a;“花”字绘制七、实战案例二&#xff1a;心型图案绘制总结 前言 Python 的 turtle 库是一种简…

【MySQL内置数据库】 mysql

目录 统计 columns_priv component db default_roles engine_cost func general_log global_grants gtid_executed help_category help_keyword help_relation help_topic innodb_index_stats innodb_table_stats ndb_binlog_index password_history plugin…

【RocketMQ】SpringBoot整合RocketMQ

&#x1f3af; 导读&#xff1a;本文档详细介绍了如何在Spring Boot应用中集成Apache RocketMQ&#xff0c;并实现消息生产和消费功能。首先通过创建消息生产者项目&#xff0c;配置POM文件引入RocketMQ依赖&#xff0c;实现同步消息发送&#xff0c;并展示了如何发送普通字符串…

STM32+ADC+扫描模式

1 ADC简介 1 ADC(模拟到数字量的桥梁) 2 DAC(数字量到模拟的桥梁)&#xff0c;例如&#xff1a;PWM&#xff08;只有完全导通和断开的状态&#xff0c;无功率损耗的状态&#xff09; DAC主要用于波形生成&#xff08;信号发生器和音频解码器&#xff09; 3 模拟看门狗自动监…

Ract vs Vue 你更喜欢谁?

React 和 Vue 是当今最受欢迎的两个前端框架&#xff0c;各自有其独特的特点和优势。以下是对这两个框架的详细比较和分析&#xff0c;以帮助你了解它们的异同和适用场景&#xff1a; React 简介 React 是由 Facebook 开发和维护的一个开源 JavaScript 库&#xff0c;主要用于…

OpenAI员工流失的背后:地盘争夺、倦怠、薪酬要求

近日&#xff0c;OpenAI的CTO Mira Murati宣布离职&#xff0c;同一天&#xff0c;首席研究官Bob McGrew、研究副总裁Barret Zoph也宣布离职。 据统计&#xff0c;这已经是2024年第11起OpenAI高管离职事件了。 至今&#xff0c;开启“ChatGPT时刻”的四位OpenAI领袖&#xff…

河南移动:核心营业系统稳定运行超300天,数据库分布式升级实践|OceanBase案例

河南移动&#xff0c;作为电信全业务运营企业&#xff0c;不仅拥有庞大的客户群体和业务规模&#xff0c;还引领着业务产品与服务体系的创新发展。河南移动的原有核心营业系统承载着超过6000万的庞大用户量&#xff0c;管理着超过80TB的海量数据&#xff0c;因此也面临着数据规…

扩散模型(2)--1

1.简介 生成模型通过学习并建模输入数据的分布&#xff0c;从而采集生成新的样木&#xff0c;该模型广泛运用于图片视频生成、文本生成和药物分子生成。扩散模型是一类概率生成模型&#xff0c;扩散模型通过向数据中逐步加入噪声来破坏数据的结构&#xff0c;然后学习一个相对应…

在Windows系统上安装的 Boost C++ 库

步骤一 https://www.boost.org/users/history/version_1_86_0.html 下载Boost库文件: 步骤二 安装: https://www.boost.org/doc/libs/1_52_0/doc/html/bbv2/installation.html 点击运行.\bootstrap.bat脚本在当前目录的powershell中执行:./b2 install --prefixPREFIX 然后…

优选拼团平台架构解析与关键代码逻辑概述

一、系统架构设计 唐古拉优选拼团平台采用多层架构设计&#xff0c;主要包括前端展示层、业务逻辑层、数据访问层及数据存储层。 前端展示层&#xff1a;负责用户界面的展示和交互&#xff0c;包括商品列表、拼团详情、订单管理等页面。前端采用现代前端框架&#xff08;如Vue…

第十四周学习周报

目录 摘要Abstract1. LSTM的代码实现2. 序列到序列模型3. 梯度与方向导数总结 摘要 在上周的学习基础之上&#xff0c;本周学习的内容有LSTM的代码实现&#xff0c;通过对代码的学习进一步加深了对LSTM的理解。为了切入到transformer的学习&#xff0c;本文通过对一些应用例子…