【纯前端excel导出】vue2纯前端导出excel,使用xlsx插件,修改样式、合并单元格

官网:

1、xlsx-js-style xlsx-js-style | xlsx-js-style homepage

2、xlsx SheetJS 中文网

一、使用第三方插件

1、安装

npm install xlsx-js-style

2、引入

import xlsx from 'xlsx-js-style'

xlsx插件是基础的导出,不可以修改样式,直接xlsx-style插件式修改样式的,所以这里直接用二者合体插件即可

二、页面使用

1、数据源

[
  {"rectifyPresideName": "朱佳佳","accepUser": "张红艳","rectifyCompleteTime": "2024-09-27 10:17:43","checkTableType": "重点时段及节假日前排查","rectifyTerm": "2024-09-27 23:59:59","rectifyDeptName": "炭黑厂炭黑车间","rectifyPlan": "建立使用记录","faultName": "岗位急救箱无使用记录","createDate": "2024年09月27日"},
  {"rectifyPresideName": "崔国梁","accepUser": "崔国梁","rectifyCompleteTime": "2024-09-26 17:13:05","checkTableType": "重点时段及节假日前排查","rectifyTerm": "2024-09-26 23:59:59","rectifyDeptName": "焦化厂第三干熄焦车间","rectifyPlan": "更换或检查修复","faultName": "疏散指示灯不亮","createDate": "2024年09月26日"},
  {"rectifyPresideName": "贾成成","accepUser": "贾成成","rectifyCompleteTime": "2024-09-26 17:23:12","checkTableType": "重点时段及节假日前排查","rectifyTerm": "2024-09-26 23:59:59","rectifyDeptName": "甲醇厂公辅车间","rectifyPlan": "安排岗位人员更换消防抢","faultName": "消防水枪损坏","createDate": "2024年09月26日"},
  {"rectifyPresideName": "王小娟","accepUser": "李学红","rectifyCompleteTime": "2024-09-25 16:50:45","checkTableType": "重点时段及节假日前排查","rectifyTerm": "2024-09-25 23:59:59","rectifyDeptName": "苯精制厂","rectifyPlan": "安装阀门","faultName": "萃取塔回流罐液位计排污阀为单阀","createDate": "2024年09月24日"}
]

2、将数据源转成需要的二维数组

const data = res.data.data.map((ele, i) => ({
          xuhao: i + 1,
          faultName: ele.faultName,
          createDate: ele.createDate,
          checkTableType: ele.checkTableType,
          rectifyPlan: ele.rectifyPlan,
          rectifyDeptName: ele.rectifyDeptName,
          rectifyPresideName: ele.rectifyPresideName,
          rectifyTerm: ele.rectifyTerm,
          rectifyCompleteTime: ele.rectifyCompleteTime,
          accepUser: ele.accepUser,
}))
const body = data.map((x) => [x.xuhao,x.faultName,x.createDate,x.checkTableType,x.rectifyPlan,x.rectifyDeptName,x.rectifyPresideName,x.rectifyTerm,x.rectifyCompleteTime,x.accepUser,])

// 转换后的二维数据
[
  [1,"岗位急救箱无使用记录","2024年09月27日","重点时段及节假日前排查","建立使用记录","炭黑厂炭黑车间","朱佳佳","2024-09-27 23:59:59","2024-09-27 10:17:43","张红艳"],
  [2,"疏散指示灯不亮","2024年09月26日","重点时段及节假日前排查","更换或检查修复","焦化厂第三干熄焦车间","崔国梁","2024-09-26 23:59:59","2024-09-26 17:13:05","崔国梁"],
  [3,"消防水枪损坏","2024年09月26日","重点时段及节假日前排查","安排岗位人员更换消防抢","甲醇厂公辅车间","贾成成","2024-09-26 23:59:59","2024-09-26 17:23:12","贾成成"],
  [4,"萃取塔回流罐液位计排污阀为单阀","2024年09月24日","重点时段及节假日前排查","安装阀门","苯精制厂","王小娟","2024-09-25 23:59:59","2024-09-25 16:50:45","李学红"]
]

3、定义表头

// 定义Excel表头
 const header = [
   ['隐患排查治理台账'],
   ['序号','问题点','检查时间','检查类别','整改措施','责任单位','责任人','整改时间','','验收人',],
   ['', '', '', '', '', '', '', '计划完成时间', '实际完成时间', ''],]

4、将定义好的表头添加到 body 中

body.unshift(...header) 

5、创建虚拟的 workbook

const workbook = xlsx.utils.book_new()

6、aoa_to_sheet 将二维数组转成 sheet

先写到这儿,明天再写,下班,886~

继续-----------

const sheet = xlsx.utils.aoa_to_sheet(body)
// aoa_to_sheet  	是将【一个二维数组】转化成 sheet
// json_to_sheet 	是将【由对象组成的数组】转化成sheet
// table_to_sheet  	是将【table的dom】直接转成sheet

7、!merges 单元格合并

①【根据实际情况合并,我这只是处理了表头】

 const merges = [
          { s: { r: 0, c: 0 }, e: { r: 0, c: 9 } },// 第0行第0列开始 —— 第0列到第9列结束(按数组的index方式计算,excel表第一列就是0开始计算)
          { s: { r: 1, c: 0 }, e: { r: 2, c: 0 } },
          { s: { r: 1, c: 1 }, e: { r: 2, c: 1 } },
          { s: { r: 1, c: 2 }, e: { r: 2, c: 2 } },
          { s: { r: 1, c: 3 }, e: { r: 2, c: 3 } },
          { s: { r: 1, c: 4 }, e: { r: 2, c: 4 } },
          { s: { r: 1, c: 5 }, e: { r: 2, c: 5 } },
          { s: { r: 1, c: 6 }, e: { r: 2, c: 6 } },
          { s: { r: 1, c: 7 }, e: { r: 1, c: 8 } },
          { s: { r: 1, c: 9 }, e: { r: 2, c: 9 } },
        ]

s:是开始的意思   r代表第几行  c代表第几列
e:是结束的意思   r代表第几行  c代表第几列

sheet['!merges'] = merges; // 添加到sheet中

②【这里处理单元格内容,后端对数据进行了排序,本项目需求就是合并三个,那我就要动态将数据一样的进行合并单元格】

 // 合并单元格的函数
    function addMerges(startRow, endRow, col) {
      if (startRow < endRow) {
         merges.push({
           s: { r: startRow, c: col },
           e: { r: endRow, c: col },
         })
       }
    }
// 动态合并相同内容的单元格的函数
   function mergeDynamicCells(colIndex) {
     let startRow = 3 // 这是单元格内容起始行
        for (let i = 4; i < body.length; i++) {
            if (body[i][colIndex] !== body[startRow][colIndex]) {
              addMerges(startRow, i - 1, colIndex) // 合并相同内容的单元格
              startRow = i // 更新起始行
       }
   }
    addMerges(startRow, body.length - 1, colIndex) // 合并最后一段相同内容
 }
// 只对第2列和第5列进行动态合并
   mergeDynamicCells(2) // 合并 2 列
   mergeDynamicCells(3) // 合并 3 列
   mergeDynamicCells(5) // 合并 5 列

 8、!cols 设置列宽

const cols = [
          { wch: 10 },
          { wch: 30 },
          { wch: 25 },
          { wch: 30 },
          { wch: 30 },
          { wch: 25 },
          { wch: 15 },
          { wch: 25 },
          { wch: 25 },
          { wch: 15 },
 ]
sheet['!cols'] = cols; // 添加到sheet中

9、!rows 设置行高

 const rows = [{ hpx: 30 }, { hpx: 30 }, { hpx: 30 }]
 sheet['!rows'] = rows // 行高添加到sheet中

10、样式添加-内容垂直居中

   let range = xlsx.utils.decode_range(sheet['!ref']);  
   let headerStyle = {  
        font: { sz: 14, name: '宋体', bold: true },  
        alignment: { vertical: 'center', horizontal: 'center' }  
    };  
   let defaultStyle = {  
        font: { sz: 11, name: '宋体' },  
        alignment: { wrapText: 1, vertical: 'center', horizontal: 'center' }  
        // wrapText: 1-------自动换行
    };  
    for (var row = range.s.r; row <= range.e.r; ++row) {  
        for (let col = range.s.c; col <= range.e.c; ++col) {  
            let cellAddress = xlsx.utils.encode_cell({ r: row, c: col });  
            let cell = sheet[cellAddress];  
            if (cell) {  
                if (!cell.s) cell.s = {};  
                // 处理表头  
                if (cell.v === '隐患排查治理台账') {  
                    cell.s = headerStyle;  
                } else {  
                    cell.s = defaultStyle;  
                }  
            }  
        }  
    }  

11、向workbook中添加sheet

 xlsx.utils.book_append_sheet(workbook, sheet, this.compname || 'Sheet')

12、导出

 xlsx.writeFile(workbook, (this.compname || 'Data') + '.xlsx', {type: 'binary',}) 

三、完整代码

expeortexcel(ids) {
 exportCheckTableFault(ids).then((res) => {
   const data = res.data.data.map((ele, i) => ({
          xuhao: i + 1,
          faultName: ele.faultName,
          createDate: ele.createDate,
          checkTableType: ele.checkTableType,
          rectifyPlan: ele.rectifyPlan,
          rectifyDeptName: ele.rectifyDeptName,
          rectifyPresideName: ele.rectifyPresideName,
          rectifyTerm: ele.rectifyTerm,
          rectifyCompleteTime: ele.rectifyCompleteTime,
          accepUser: ele.accepUser,
        }))
        const body = data.map((x) => [
          x.xuhao,
          x.faultName,
          x.createDate,
          x.checkTableType,
          x.rectifyPlan,
          x.rectifyDeptName,
          x.rectifyPresideName,
          x.rectifyTerm,
          x.rectifyCompleteTime,
          x.accepUser,
        ])
        // 定义Excel表头
        const header = [
          ['隐患排查治理台账'],
          [
            '序号',
            '问题点',
            '检查时间',
            '检查类别',
            '整改措施',
            '责任单位',
            '责任人',
            '整改时间',
            '',
            '验收人',
          ],
          ['', '', '', '', '', '', '', '计划完成时间', '实际完成时间', ''],
        ]
 body.unshift(...header) // 将定义好的表头添加到 body 中
 const sheet = xlsx.utils.aoa_to_sheet(body) // aoa_to_sheet 将二维数组转成 sheet
 // 合并单元格的函数
        const merges = [
          { s: { r: 0, c: 0 }, e: { r: 0, c: 9 } },
          { s: { r: 1, c: 0 }, e: { r: 2, c: 0 } },
          { s: { r: 1, c: 1 }, e: { r: 2, c: 1 } },
          { s: { r: 1, c: 2 }, e: { r: 2, c: 2 } },
          { s: { r: 1, c: 3 }, e: { r: 2, c: 3 } },
          { s: { r: 1, c: 4 }, e: { r: 2, c: 4 } },
          { s: { r: 1, c: 5 }, e: { r: 2, c: 5 } },
          { s: { r: 1, c: 6 }, e: { r: 2, c: 6 } },
          { s: { r: 1, c: 7 }, e: { r: 1, c: 8 } },
          { s: { r: 1, c: 9 }, e: { r: 2, c: 9 } },
        ]
       function addMerges(startRow, endRow, col) {
          if (startRow < endRow) {
            merges.push({
              s: { r: startRow, c: col },
              e: { r: endRow, c: col },
            })
          }
        }
        // 动态合并相同内容的单元格的函数
        function mergeDynamicCells(colIndex) {
          let startRow = 3 // 数据部分从第4行开始
          for (let i = 4; i < body.length; i++) {
            if (body[i][colIndex] !== body[startRow][colIndex]) {
              addMerges(startRow, i - 1, colIndex) // 合并相同内容的单元格
              startRow = i // 更新起始行
            }
          }
          addMerges(startRow, body.length - 1, colIndex) // 合并最后一段相同内容
        }
        // 只对第2列和第5列进行动态合并
        mergeDynamicCells(2) // 合并 2 列
        mergeDynamicCells(3) // 合并 3 列
        mergeDynamicCells(5) // 合并 5 列
        sheet['!merges'] = merges // 将合并信息添加到 sheet 中
        const cols = [
          { wch: 10 },
          { wch: 30 },
          { wch: 25 },
          { wch: 30 },
          { wch: 30 },
          { wch: 25 },
          { wch: 15 },
          { wch: 25 },
          { wch: 25 },
          { wch: 15 },
        ]
        sheet['!cols'] = cols // 设置列宽
        const rows = [{ hpx: 30 }, { hpx: 30 }, { hpx: 30 }]
        sheet['!rows'] = rows // 设置行高
        // 合并居中表格内容
        var range = xlsx.utils.decode_range(sheet['!ref'])
        for (var R = range.s.r; R <= range.e.r; ++R) {
          for (var C = range.s.c; C <= range.e.c; ++C) {
            var cell_ref = xlsx.utils.encode_cell({ r: R, c: C })
            var cell = sheet[cell_ref]
            if (cell) {
              if (!cell.s) cell.s = {}
              if (cell.v == '隐患排查治理台账') {
                cell.s = {
                  font: {
                    sz: 14,
                    name: '宋体',
                    bold: true,
                  },
                  alignment: {
                    vertical: 'center', // 垂直居中
                    horizontal: 'center', // 水平居中
                  },
                }
              } else {
                cell.s = {
                  font: {
                    sz: 11,
                    name: '宋体',
                  },
                  alignment: {
                    wrapText: 1, //自动换行
                    vertical: 'center', // 垂直居中
                    horizontal: 'center', // 水平居中
                  },
                }
              }
            }
          }
        }
        const workbook = xlsx.utils.book_new()
xlsx.utils.book_append_sheet(workbook, sheet, this.compname || 'Sheet') // 向workbook中添加sheet
xlsx.writeFile(workbook, (this.compname || 'Data') + '.xlsx', {type: 'binary',}) // 导出 workbook})},

借鉴:前端使用xlsx-js-style导出Excel文件并修饰单元格样式-CSDN博客

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

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

相关文章

基于SSM校园拼车系统的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;学生管理&#xff0c;司机管理&#xff0c;订单信息管理&#xff0c;接单信息管理&#xff0c;留言信息管理 司机账号功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;订单信息管理&…

用Spring AI 做智能客服,基于私有知识库和RAG技术

Java智能客服系统运用RAG技术提升答疑精准度 基于Spring ai 的 RAG&#xff08;检索增强生成&#xff09;技术&#xff0c;Java智能客服系统能够利用私有知识库中的信息提供更准确的答疑服务。 它的核心思路是&#xff1a; 首先&#xff0c;将客服QA以Word形式导入到系统中&…

vr体验馆计时收银软件试用版下载 佳易王VR游戏厅计时计费管理系统使用操作教程

一、前言 【软件试用版资源文件下载可以点击文章最后卡片了解】 vr体验馆计时收银软件试用版下载 佳易王VR游戏厅计时计费管理系统使用操作教程 VR体验馆计时计费软件是专门为VR体验馆设计的管理工具&#xff0c;旨在提高服务效率和客户的满意度。软件能够记录客户使用设备的…

Windows 通过私钥远程连接 Linux 服务器【含密钥对制作】

在现代软件开发和系统管理中&#xff0c;远程连接 Linux 服务器是非常常见的任务。尤其在 Windows 系统下&#xff0c;使用 SSH 工具连接 Linux 服务器是开发者们不可或缺的技能之一。为了保证安全性&#xff0c;SSH 密钥对&#xff08;公钥和私钥&#xff09;的使用可以避免传…

STM32CUBEIDE FreeRTOS操作教程(七):queue队列

STM32CUBEIDE FreeRTOS操作教程&#xff08;七&#xff09;&#xff1a;queue队列 STM32CUBE开发环境集成了STM32 HAL库进行FreeRTOS配置和开发的组件&#xff0c;不需要用户自己进行FreeRTOS的移植。这里介绍最简化的用户操作类应用教程。以STM32F401RCT6开发板为例&#xff…

家用wifi的ip地址固定吗?换wifi就是换ip地址吗

在探讨家用WiFi的IP地址是否固定&#xff0c;以及换WiFi是否就意味着换IP地址这两个问题时&#xff0c;我们首先需要明确几个关键概念&#xff1a;IP地址、家用WiFi网络、以及它们之间的相互作用。 一、家用WiFi的IP地址固定性 家用WiFi环境中的IP地址通常涉及两类&#xff1a…

[Unity Demo]从零开始制作空洞骑士Hollow Knight第十四集:制作新的场景以及制作创建切换管理系统

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、制作新的场景 1.重新翻新各种Sprite2.制作地图前期应该做的事情3.疯狂的制作地图二、制作场景切换管理系统 1.制作场景切换点TransitionPoint2.切换场景时的…

【Linux内核】eBPF基础篇

系列综述&#xff1a; &#x1f49e;目的&#xff1a;本系列是个人整理为了学习ebpf机制的&#xff0c;整理期间苛求每个知识点&#xff0c;平衡理解简易度与深入程度。 &#x1f970;来源&#xff1a;材料主要源于–知乎ebpf专栏文章–进行的&#xff0c;每个知识点的修正和深…

【JavaEE初阶】深入理解TCP协议中的封装分用以及UDP和TCP在网络编程的区别

前言 &#x1f31f;&#x1f31f;本期讲解关于TCP/UDP协议的原理理解~~~ &#x1f308;上期博客在这里&#xff1a;【JavaEE初阶】入门视角-网络原理的基础理论的了解-CSDN博客 &#x1f308;感兴趣的小伙伴看一看小编主页&#xff1a;GGBondlctrl-CSDN博客 &#x1f525; …

前端算法:时间复杂度和空间复杂度

一、算法的重要性 1.为什么前端开发需要学习算法&#xff1f; 学习算法可以帮助培养逻辑思维能力&#xff0c;在面对复杂的问题时&#xff0c;能够系统性地分析问题、分解步骤并成功找到的正确的解决方案。 掌握基本的排序、查找算法和时间复杂度分析可以帮助编写更高效的代码…

移动网络知识

一、3G网络 TD-SCDMA&#xff08;时分同步码分多址接入&#xff09;、WCDMA&#xff08;宽带码分多址&#xff09;和CDMA2000三种不同的3G移动通信标准 TD-SCDMA&#xff08;时分同步码分多址接入&#xff09;&#xff1a;中国自主开发的一种3G标准主要用于国内市场&#xff…

零跑“半价平替”杀疯了,没钱别硬上问界理想

文 | AUTO芯球 作者 | 雷慢 你绝对想不到&#xff0c; 现在造车新势力的周销量榜第二名已经是零跑了 来看啊&#xff0c;十月第2周&#xff0c; 零跑周销量8700量&#xff0c;已经超过问界的7100辆&#xff0c; 放以前&#xff0c;问界也是周销量9000台左右的主&#xff0…

RHCE——时间服务器

NTP——网络时间协议&#xff0c;通过udp123端口进行网络时钟同步 chronyd chronyd——一个开源自由的网络时间协议 NTP 的客户端和服务器软件。能让计算机保持系统时钟与时钟服务器&#xff08;NTP&#xff09;同步&#xff0c;从而使计算机保持精确的时间。 Chrony由两个程…

大数据查询引擎之Tez

Apache Tez 是一个用于大数据处理的分布式计算框架&#xff0c;旨在提高 Hadoop 的 MapReduce 计算引擎的效率和性能。它是一个面向 DAG&#xff08;有向无环图&#xff09;任务执行的框架&#xff0c;主要用于大规模数据处理场景中&#xff0c;特别是在 Apache Hadoop 生态系统…

开放式耳机好不好用?盘点开放式蓝牙耳机排行榜前五名

​开放式耳机是好用的&#xff0c;目前非常流行&#xff0c;它们以时尚、美观和舒适著称&#xff0c;迅速赢得了众多用户的喜爱&#xff0c;成为了耳机市场的新宠。与传统的入耳式耳机相比&#xff0c;开放式耳机佩戴更稳固&#xff0c;对耳朵也更为温和。尽管有些人认为它们价…

C++在vscode中的code runner配置/环境配置

C在vscode中快捷运行&#xff08;code runner&#xff09; 一、配置tasks.json 在vscode中创建文件夹或打开文件夹&#xff0c;会发现文件夹下多了一个.vscode文件夹&#xff0c;在该文件夹下创建tasks.json文件&#xff0c;并添加一下内容 {"version": "2.0…

单周期处理器设计思路

目录 单周期处理器设计思路加法器的优化行波进位加法器&#xff08;RCA&#xff09;先行进位加法器&#xff08;CLA&#xff09;两种加法器的对比CLA的再优化可以用加法器实现的其他操作 编写可维护的RTL代码 单周期处理器设计思路 加法器的优化 &#xff08;用综合器综合*/等…

如何修改MAC地址破解网络无线网络限制-担心别人蹭网,路由器设置MAC地址过滤,限定了能访问无线网络的网卡地址-供大家学习参考

路由器都设置了MAC地址过滤&#xff0c;也就是限定了能访问无线网络的网卡的MAC地址。因为无线路由器不一定由自己控制&#xff0c;所以当更换了笔记本或者更换了无线网卡的时候&#xff0c;也许就上不了网了。我们可以修改网卡的MAC地址实现上网。 下载&#xff1a;https://do…

R01 vue+springboot 高考志愿推荐AI问答大数据平台

可以查看本文系统对应的视频讲解&#xff1a; vuespringboot 高考推荐AI问答志愿推荐大数据 R01 带增删改查、大屏、支持爬虫 1 系统背景 近年来&#xff0c;高考作为中国教育体系中最重要的考试之一&#xff0c;承载了无数考生和家庭的梦想。随着信息技术的迅猛发展&#xff…

Linux shell脚本文件通过shc工具加密,生成静态链接可执行文件

要使用 shc 工具对 Linux shell 脚本进行加密并生成静态链接的可执行文件&#xff0c;你可以按照以下步骤操作&#xff1a; 安装 shc 工具&#xff1a; 如果你的系统中还没有安装 shc&#xff0c;可以通过包管理器安装&#xff0c;例如在 Ubuntu 系统中&#xff0c;可以使用以下…