vue中使用exceljs和file-saver插件实现纯前端表格导出Excel(支持样式配置,多级表头)

实现:使用Excel.js库创建excel文件,然后再使用 file-saver库将 Excel 文件保存到用户的本地计算机。

1.安装,可以使用npm,yarn

npm install exceljs
npm install file-saver

 2.封装生成excel的方法
// 封装exceljs
const ExcelJS = require('exceljs');
const FileSaver = require('file-saver');exportDataToExcel(config, fileName) {if (!config) return;const options = {fileName: fileName || `导出excel文件【${Date.now()}】.xlsx`,worksheets: []}if(!Array.isArray(config)) {config = [config]}config.forEach((item) => {// 深拷贝data【JSON.stringify有缺陷,可自行换成_.cloneDeep】const data = JSON.parse(JSON.stringify(item.data));const results = data.map(obj => {return item.fields.map(key => {return obj[key]})})// 生成完整excel数据let excelData = [];excelData = excelData.concat(item.headers).concat(results);// 单元格合并处理【excel数据的第一行/列是从1开始】let excelMerges = [];excelMerges = item.merges.map(m => {return [m.row + 1, m.col + 1, m.row + m.rowspan, m.col + m.colspan]})// 单元格配置处理 excel数据的第一行/列是从1开始】let excelAttrs = [];excelAttrs = item.attrs.map(attr => {attr.rowStart += 1;attr.rowEnd += 1;attr.colStart += 1;attr.colEnd += 1;return attr})options.worksheets.push({data: excelData,merges: excelMerges,attrs: excelAttrs,views: item.views,columnsWidth: item.columnsWidth,protect: item.protect,sheetName: item.sheetName})})this.createExcel(options)
},// 创建Excel文件方法
async createExcel(options) {if (!options.worksheets.length) return;// 创建工作簿const workbook = new ExcelJS.Workbook();for (let i = 0; i < options.worksheets.length; i++) {const sheetOption = options.worksheets[i];// 创建工作表const sheet = workbook.addWorksheet(sheetOption.sheetName || 'sheet' + (i + 1));// 添加数据行sheet.addRows(sheetOption.data);// 配置视图sheet.views = sheetOption.views;// 单元格合并处理【开始行,开始列,结束行,结束列】if (sheetOption.merges){sheetOption.merges.forEach((item) => {sheet.mergeCells(item) });}// 工作表保 if (sheetOption.protect) {const res = await sheet.protect(sheetOption.protect.password, sheetOption.protect.options);}// 单元格样式处理if (sheetOption.attrs.length) {sheetOption.attrs.forEach((item) => {const attr = item.attr || {};// 获取开始行-结束行; 开始列-结束列const rowStart = item.rowStart;const rowEnd = item.rowEnd;const colStart = item.colStart;const colEnd = item.colEnd;if (rowStart) { // 设置行for (let r = rowStart; r <= rowEnd; r++) {// 获取当前行const row = sheet.getRow(r);if (colStart) { // 列设置for (let c = colStart; c <= colEnd; c++) {// 获取当前单元格const cell = row.getCell(c);Object.keys(attr).forEach((key) => {// 给当前单元格设置定义的样式cell[key] = attr[key];});}} else {// 未设置列,整行设置【大纲级别】Object.keys(attr).forEach((key) => {row[key] = attr[key];});}}} else if (colStart) { // 未设置行,只设置了列for (let c = colStart; c <= colEnd; c++) {// 获取当前列,整列设置【大纲级别】const column = sheet.getColumn(c);Object.keys(attr).forEach((key) => {column[key] = attr[key];});}} else {// 没有设置具体的行列,则为整表设置Object.keys(attr).forEach((key) => {sheet[key] = attr[key];});}})}// 列宽设置if (sheetOption.columnsWidth) {for (let i = 0; i < sheet.columns.length; i++) {sheet.columns[i].width = sheetOption.columnsWidth[i]}}}// 生成excel文件workbook.xlsx.writeBuffer().then(buffer => {// application/octet-stream 二进制数据FileSaver.saveAs(new Blob([buffer], { type: 'application/octet-stream' }), options.fileName)})}
3.在项目中使用
exportExcel(){const header = [["所在部门","隐患总数","已整改隐患数","整改中隐患数","整改率","一般隐患","","","","较大隐患","","","","重大隐患","","",""],["","","","","","隐患数","已整改数","整改中数","整改率(%)","隐患数","已整改数","整改中数","整改率(%)","隐患数","已整改数","整改中数","整改率(%)"]]const fields = ["name","count","count_yzg","count_zgz","zgl","count_common","count_common_yzg","count_common_zgz","ybyh_zgl","count_bigger","count_bigger_yzg","count_bigger_zgz","jdyh_zgl","count_biggest","count_biggest_yzg","count_biggest_zgz","zdyh_zgl"]const merges = [//导出表格的第一行第一列,行合并2个单元格,列就用自己的一个;{row: 0, col: 0, rowspan: 2, colspan: 1},{row: 0, col: 1, rowspan: 2, colspan: 1},{row: 0, col: 2, rowspan: 2, colspan: 1},{row: 0, col: 3, rowspan: 2, colspan: 1},{row: 0, col: 4, rowspan: 2, colspan: 1},{row: 0, col: 5, rowspan: 1, colspan: 4},{row: 0, col: 9, rowspan: 1, colspan: 4},{row: 0, col: 13, rowspan: 1, colspan: 4},]const config = this.exportConfig(header,fields,merges,this.tabledata[this.type]);//配置this.$utils.exportDataToExcel(config, "隐患治理情况统计表.xlsx");},//导出表格配置exportConfig(header = [], fields = [], merges = [], tableData = []){// console.log(header, fields, merges, tableData );// return//配置表头header1为一级表头,header2为二级表头,被合并的单元格为空写占位符"":// 如果导出前要处理数据,需要深克隆一份表格数据,然后进行处理const exportTableData = JSON.parse(JSON.stringify(tableData));const config = {data: exportTableData,//exportTableData为表格数据,为空的话,导出表格只显示表头fields: fields,headers: header,merges: merges,attrs: [],view: [],columnsWidth: [20, 20, 20, 20, 20,20, 20,20, 20, 20, 20, 20,20, 20,20,20],//每行列的宽// protect: {},sheetName: "个人信息"};// 设置全表单元格边框,居中布局config.attrs.push({rowStart: 0,rowEnd: config.data.length + 1,//表格表头多几层,就加几个colStart: 0,colEnd: config.fields.length - 1,attr: {alignment: { vertical: "middle", horizontal: "center" },border: {top: { style: "thin" },left: { style: "thin" },bottom: { style: "thin" },right: { style: "thin" }}}});// 设置表头填充颜色,字体加粗config.attrs.push({rowStart: 0,rowEnd: 1,//表格表头多几层,就写几colStart: 0,colEnd: config.fields.length - 1,attr: {fill: {type: "pattern",pattern: "solid",fgColor: { argb: "c5c8ce" }},font: {bold: true}}});return config;}

/**

     * 导出数据到Excel 传参参数

     * config.data 表格数据

     * config.fields 字段列表

     * config.headers excel表头列表[[]],可以是多级表头[['A1','B1'],['A2','B2']]

     * config.merges 需要合并的单元格,需要考虑表头的行数[{row:1, col:1, rowspan: 1, colspan: 2}]

     * config.attrs 单元格样式配置

     * config.views 工作表视图配置

     * columnsWidth 每个字段列对应的宽度

     * config.protect 工作表保护【此配置会保护全表,一般推荐只针对单元格进行保护配置】

     * sheetName 工作表名称,默认从sheet1开始

     * fileName excel文件名称

     */

页面效果:

导出excel效果

 

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

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

相关文章

H5 随机身份证号码、社会统一信用代码、手机号、名字、银行卡号码

平时注册可能会用到这些&#xff0c;原本用自己服务器搭了个&#xff0c;感觉纯前端的还能引入到项目中挺好的&#xff0c;之后再追加一些常用的随机数据&#xff0c;这样写表单应该就会好测试了(●’◡’●)。 在线链接 https://linyisonger.github.io/H5.Examples/?name./07…

Brave编译指南2024 MacOS篇-初始化构建环境(五)

引言 在上一篇文章中&#xff0c;我们完成了Brave浏览器编译所需的环境配置。现在&#xff0c;我们将进入下一个关键阶段&#xff1a;初始化构建环境。这个步骤将确保我们有一个完整的、准备就绪的开发环境&#xff0c;包括所有必要的依赖项和Chromium源代码。 1. 切换工作目…

上海沪鑫餐饮供应链:嘉定蔬菜配送分拣工作的精细艺术

在餐饮行业的背后&#xff0c;有一条默默运作的关键链条——餐饮供应链。而在上海沪鑫餐饮管理有限公司&#xff08;简称沪鑫餐饮供应链、沪鑫食材&#xff09;中&#xff0c;嘉定蔬菜配送分拣工作犹如一场精心编排的舞蹈&#xff0c;每一个动作都决定着最终呈现在餐桌上的美食…

文件和目录

文件和目录 获取文件属性 通过 ls 命令可以查看到文件的很多属性内容&#xff0c;这些文件属性的内容可以通过以下几个函数获取: #include <sys/types.h> #include <sys/stat.h> #include <unistd.h>int stat(const char *pathname, struct stat *statbuf…

ISA Server配置https踩坑全过程

首先普通的http配置请参考 【ISA Server 2006发布Web网站】 https://www.bilibili.com/video/BV1qc411v75w/?share_sourcecopy_web&vd_sourcef35b2f2d0d34140bcba81b8b6f8c1b69 本文只一笔带过&#xff0c;讲一下https部分。 正解 由于我维护的是windows server 2003的…

计算机毕业设计 招生宣传管理系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

C语言扫盲

文章目录 C版本C语言特征GCCprintf数据类型函数指针内存管理void指针 Struct结构和Union结构typedef预处理器make工具cmake工具Projectintegral of sinc functionemulator embedded systeman event schedule 补充在线Linux终端安装Linux参考 建议还是国外教材学习…人家的PPT比…

物联网系统中OLED屏主流驱动方案详解

01 物联网系统中为什么要使用OLED驱动芯片 卓越的显示效果 1、高对比度和鲜艳色彩&#xff1a;OLED屏幕能够自发光&#xff0c;因此能够实现极高的对比度和鲜艳的色彩表现&#xff0c;这在物联网设备的显示界面上尤为重要&#xff0c;可以为用户提供更清晰、更生动的视觉体验…

[论文精读]TorWard: Discovery, Blocking, and Traceback of Malicious Traffic Over Tor

期刊名称&#xff1a;IEEE Transactions on Information Forensics and Security 发布链接&#xff1a;TorWard: Discovery, Blocking, and Traceback of Malicious Traffic Over Tor | IEEE Journals & Magazine | IEEE Xplore 中文译名&#xff1a;TorWard&#xff1a;…

jvm专题 之 内存模型

文章目录 前言一个java对象的运行过程jvm内存分布程序的基本运行程序对象什么是对象对象的创建一、类加载检查二、对象内存分配三、初始化零值四、设置对象头五、执行初始化方法 对象的访问定位 对象与类的关系由类创建对象的顺序 对象的创建 前言 一个程序需要运行&#xff0…

JNI实现Java调用C++函数

1. 测试环境 操作系统&#xff1a;win10JDK版本&#xff1a;JDK11 安装教程gcc版本&#xff1a;8.1.0 2. 声明native方法 // HelloJNI.java public class HelloJNI {// 输出Hello JNI from CPP. private native static void sayHello();// 实现两个整数相加private native s…

Android手机投屏方案实现方式对比

文章目录 1.概述2.术语解释2.1 miracast2.2 scrcpy2.4 Wifi Direct2.5 app_process 3.技术实现对比3.1 Miracast3.1.1 Miracast介绍3.1.2 Miracast原理3.1.3 Miracast优缺点分析 3.2 Scrcpy3.2.1 scrcpy 介绍3.2.2 scrcpy的实现原理3.2.3 scrcpy的优缺点分析 3.3 Google cast3.…

【学习笔记】手写 Tomcat 四

目录 一、Read 方法返回 -1 的问题 二、JDBC 优化 1. 创建配置文件 2. 创建工具类 3. 简化 JDBC 的步骤 三、修改密码 优化返回数据 创建修改密码的页面 注意 测试 四、优化响应动态资源 1. 创建 LoginServlet 类 2. 把登录功能的代码放到 LoginServlet 类 3. 创…

Python 算法交易实验89 QTV200日常推进-模式思考

说明 过去几天大A的表现还是比较戏剧化的。 让我想到了&#xff1a; 1 价稳量缩模式。之前很长一段时间都是这种状态&#xff0c;最终还是大爆发了&#xff0c;这个可取。2 周期模式。假设价格是一个周期为T(T可变)的正弦波&#xff0c;所以最终还是回到了几个月前的位置&…

UE学习篇ContentExample解读------Blueprints Advanced-下

文章目录 总览描述批次阅览2.1 Timeline animation2.2 Actor tracking2.3 Button Trigger using a blueprint interface2.4 Opening door with trigger2.5 Child Blueprints 概念总结致谢&#xff1a; 总览描述 打开关卡后&#xff0c;引入眼帘的就是针对关卡的总体性文字描述&…

物联网系统中基于IIC通信的数字温度传感器测温方案

01 物联网系统中为什么要使用数字式温度传感器芯片 物联网系统中使用数字式温度传感器芯片的原因主要有以下几点&#xff1a; 高精度与稳定性 高精度测量&#xff1a;数字式温度传感器芯片&#xff0c;如DS18B20&#xff0c;采用芯片集成技术&#xff0c;能够有效抑制外界不…

算法宝典——二分查找算法

1.认识二分查找 二分查找的时间复杂度:O(logN) 二分查找属于算法中耳熟能详的一类&#xff0c;通常的我们会说只有数组有序才可以使用二分查找&#xff0c;不过这种说法并不完全正确&#xff0c;只要数据具有"二段性"就可以使用二分查找&#xff0c;即我们可以找出一…

【零散技术】Odoo PDF 打印问题问题合集

序言:时间是我们最宝贵的财富,珍惜手上的每个时分 Odoo PDF打印 是一个必备功能&#xff0c;但是总会遇到一些奇奇怪怪的问题&#xff0c;此帖仅做记录&#xff0c;方便查阅。 目录 1、样式丢失 2、部分结构丢失 3、没有中文字体 1、样式丢失 这种情况一般是由于 …

ppt压缩有什么简单方法?压缩PPT文件的几种方法

ppt压缩有什么简单方法&#xff1f;许多用户常常面临文件过大的问题&#xff0c;尤其在需要通过电子邮件发送或上传至网络平台时&#xff0c;大文件会带来诸多麻烦。此外&#xff0c;较大的文件可能导致软件响应缓慢&#xff0c;从而影响整体的演示体验。因此&#xff0c;寻找有…

C++ 基础入门-命名空间、c++的输入输出、缺省参数、函数重载、引用、内联函数超详细讲解

这篇文章主要对c的学习做一个基础铺垫&#xff0c;方便后续学习。主要通过示例讲解命名空间、c的输入输出cout\cin&#xff0c;缺省参数、函数重载、引用、内联函数&#xff0c;auto关键字&#xff0c;for循环&#xff0c;nullptr以及涉及到的周边知识&#xff0c;面试题等。为…