前端导出数据到Excel(Excel.js导出数据)

库:Excel.js(版本4.3.0) 和 FileSaver(版本2.0.5)

CDN地址:

<script src="https://cdn.bootcdn.net/ajax/libs/exceljs/4.3.0/exceljs.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/FileSaver.js/2.0.5/FileSaver.js"></script>

Excel.js 中文文档:https://gitee.com/alan_scut/exceljs

先看一下效果吧
在这里插入图片描述

代码:

使用方法: exportExcal()

// 住宿安排(动态列)
var stay_arr = ['27日晚', '28日晚'];
// 内容数据
var test_data = [{"guest": "生态伙伴","name": "姓名一","sex": "男","company": "AAAAAA股份有限公司","job": "业务部部长","phone": "12345678912","stay": ["28日晚"]},{"guest": "生态伙伴","name": "姓名二","sex": "女","company": "AAAAAA股份有限公司","job": "业务部部长","phone": "12345678912","stay": ["27日晚","28日晚",]}
];
// 导出Excel
function exportExcal() {// 文件名称var fileName = 'simple.xlsx';// 固定内容的列数var basic_col_num = 7;// 总列数(固定列+住宿动态列的长度)var all_column_num = basic_col_num + stay_arr.length;// 表单数据数组var data_arr = [];// 数据单元格起始行数var rowStart = 4;// 基础单元格边框样式var borderStyle = {top: { style: "thin", color: { argb: "FF000000" } },left: { style: "thin", color: { argb: "FF000000" } },bottom: { style: "thin", color: { argb: "FF000000" } },right: { style: "thin", color: { argb: "FF000000" } },}// 基础内容对齐方式var basicAlignment = { vertical: 'middle', horizontal: 'center', wrapText: true };// 新建工作簿var wb = new ExcelJS.Workbook();// 设置工作簿属性wb.creator = 'Me';                      // 作者wb.lastModifiedBy = 'Her';              // 最后修改人wb.created = new Date(2023, 10, 10);     // 创建时间wb.modified = new Date();               // 修改时间wb.lastPrinted = new Date(2023, 10, 10); // 上次打印文档时间wb.properties.date1904 = true;          // 将工作簿日期设置为1904日期系统// 向新的工作簿中增加一张工作表var ws = wb.addWorksheet('邀约名单');// 设置默认行高ws.properties.defaultRowHeight = 20;// 也可以在添加工作表的时候直接设置参数// var ws = wb.addWorksheet('邀约名单', {properties:{defaultRowHeight:20}});// 表头部分开始// 设置单元格第一行// 获取单元格内第一行var collectRow = ws.getRow(1);// 设置单行行高collectRow.height = 40;// 设置整行的文字样式collectRow.style.font = { name: 'Microsoft YaHei', size: 16, bold: true, color: { argb: "ffffffff" } };// 设置整行内容对齐方式collectRow.alignment = basicAlignment;// 获取A1单元格var collectcell = ws.getCell(`A1`);// 表格第一行标题内容,A1合并后填充的内容collectcell.value = `参会信息统计表`;// 设置单个单元格的背景色(这里不能设置整行,因为会超出数据的宽度)collectcell.fill = {type: "pattern",pattern: "solid",fgColor: { argb: "ff538dd5" },}// 设置单个单元格的边框样式collectcell.border = {top: { style: "thin", color: { argb: "FF000000" } },left: { style: "thin", color: { argb: "FF000000" } },right: { style: "thin", color: { argb: "FF000000" } },};// 合并单元格,将A1与H1合并(ws.mergeCells(`A1:H1`);)ws.mergeCells(`A1:${getLetter(all_column_num)}1`);// 设置单元格第二行// 获取单元格内第二行var collectRow = ws.getRow(2);// 设置单行行高collectRow.height = 26;// 获取A2单元格var collectcell2 = ws.getCell(`A2`);// 表格第二行标题内容,A2合并后填充的内容collectcell2.value = `活动时间:2023年10月10日        活动地点:XXXXXXX会议中心        住宿酒店:XXXX酒店`;// 单独设置单元格的文字样式collectcell2.font = { name: 'Microsoft YaHei', size: 10, bold: false, color: { argb: "ffffffff" } }; // 字体// 单独设置单元格的背景色collectcell2.fill = {type: "pattern",pattern: "solid",fgColor: { argb: "ff538dd5" },}// 单独设置单元格的内容对齐方式collectcell2.alignment = basicAlignment;// 单独设置单元格的边框样式collectcell2.border = {left: { style: "thin", color: { argb: "FF000000" } },bottom: { style: "thin", color: { argb: "FF000000" } },right: { style: "thin", color: { argb: "FF000000" } },};// 合并单元格,将A2与H2合并(ws.mergeCells(`A2:H2`);)ws.mergeCells(`A2:${getLetter(all_column_num)}2`);// 处理表单第三行第四行每个单元格表头内容for (let i = 1; i <= all_column_num; i++) {let r3cell = ws.getCell(`${getLetter(i)}3`); // 获取第三行的单元格let r4cell = ws.getCell(`${getLetter(i)}4`); // 获取第三行的单元格// 设置内容对齐方式r3cell.alignment = basicAlignment;r4cell.alignment = basicAlignment;// 前面部分固定内容的表头设置if (i <= basic_col_num) {// 设置单元格样式r3cell.border = borderStyle;r3cell.fill = {type: "pattern",pattern: "solid",fgColor: { argb: "ff808080" },}r3cell.font = { name: 'Microsoft YaHei', size: 11, bold: true, color: { argb: "ffffffff" } };switch (i) {case 1:ws.getCell(`${getLetter(i)}3`).value = "序号";// 设置单元格宽度(宽度单位是字符宽度,而不是像素宽度,中文是两个字符)ws.getColumn(i).width = 6;break;case 2:ws.getCell(`${getLetter(i)}3`).value = "嘉宾类别";ws.getColumn(i).width = 16;break;case 3:ws.getCell(`${getLetter(i)}3`).value = "姓名";ws.getColumn(i).width = 10;break;case 4:ws.getCell(`${getLetter(i)}3`).value = "性别";ws.getColumn(i).width = 6;break;case 5:ws.getCell(`${getLetter(i)}3`).value = "单位";ws.getColumn(i).width = 40;break;case 6:ws.getCell(`${getLetter(i)}3`).value = "职务";ws.getColumn(i).width = 24;break;case 7:ws.getCell(`${getLetter(i)}3`).value = "手机号";ws.getColumn(i).width = 15;break;}// 合并上下对应的单元格ws.mergeCells(`${getLetter(i)}3:${getLetter(i)}4`);} else {// 这部分是动态的单元格// 设置单元格宽度ws.getColumn(i).width = 12;// 住宿部分表头样式需要分开设置(因为不合并)r3cell.border = borderStyle;r3cell.fill = {type: "pattern",pattern: "solid",fgColor: { argb: "ffebf1de" },}r4cell.border = borderStyle;r4cell.fill = {type: "pattern",pattern: "solid",fgColor: { argb: "ffebf1de" },}r4cell.font = { name: 'Microsoft YaHei', size: 11, bold: true, color: { argb: "ff595959" } };// 住宿第三行的内容if (i == (basic_col_num + 1)) {ws.getCell(`${getLetter(i)}3`).value = "行程安排";// 合并单元格(行程安排)ws.mergeCells(`${getLetter(i)}3:${getLetter(i + stay_arr.length - 1)}3`);}// 设置住宿列第四行的动态内容ws.getCell(`${getLetter(i)}4`).value = stay_arr[i - basic_col_num - 1];}}// 处理表单数据for (let i = 0; i < test_data.length; i++) {// 序号,嘉宾类别,姓名,性别,单位,职务,手机号data_arr[i] = [i + 1,test_data[i].guest,test_data[i].name,test_data[i].sex,test_data[i].company,test_data[i].job,test_data[i].phone]// 动态添加住宿(循环住宿内容数组)for (let j = 0; j < stay_arr.length; j++) {if (test_data[i].stay) {// 判断该值是否是列表中数据内存在的值if (test_data[i].stay.indexOf(stay_arr[j]) != -1) {data_arr[i].push("是");} else {data_arr[i].push("");}} else {// 如果没有住宿,直接添加空data_arr[i].push("");}}}// 将表单输入插入行for (let i = 0; i < data_arr.length; i++) {// 获取数据行let r_data = ws.getRow(i + rowStart + 1);// 设置整行单元格的内容对其方式r_data.alignment = basicAlignment;// 字体r_data.font = { name: 'Microsoft YaHei', size: 11, bold: false, color: { argb: "ff000000" } };// 设置整行的数据内容r_data.values = data_arr[i];// 循环本行插入的每个单元格,然后给单元格设置边框样式(注意,一定要插入数据后,才能循环设置)// 这里不能用 设置整行边框,因为单元格会超出,不好看了r_data.eachCell({ includeEmpty: true }, function (cell, colNumber) {ws.getCell(`${getLetter(colNumber)}${i + rowStart + 1}`).border = borderStyle});}// node端才能使用// wb.xlsx.writeFile(fileName).then(() => {//   console.log('file created');// }).catch(err => {//   console.log(err.message);// });wb.xlsx.writeBuffer().then(buffer => {// 这里之前是 FileSaver.saveAs 因为报错换成 window.saveAs 原因文章后面有说window.saveAs(new Blob([buffer], { type: 'application/octet-stream' }), `${fileName || 'excel.xlsx'}`);})
}// 获取第N个字母
function getLetter(num) {return String.fromCharCode(64 + num);
}

代码中用到的方法总结:

新建工作簿 & 向工作簿中增加一张工作表

var workbook = new ExcelJS.Workbook();
var worksheet = workbook.addWorksheet(‘邀约名单’);

合并单元格(将A1与H1合并)

worksheet.mergeCells(‘A1:H1’);

获取行(第一行)

var collectRow = worksheet.getRow(1);

获取列(B或者3)

var collectcell = worksheet.getColumn(‘B’);
var collectcell = worksheet.getColumn(3);

获取单元格(A2)

var collectcell = worksheet.getCell(‘A2’);

设置单元格内容(行、列、单元格均可设置。行、列是赋值数组)

var collectcell = worksheet.getCell(‘A2’);
collectcell.value = ‘活动时间’;

设置单元格宽度(列、单元格均可设置。宽度单位是字符宽度,而不是像素宽度,中文是两个字符。)

var collectcell = worksheet.getCell(‘A2’);
collectcell.width = 6;

设置工作表的默认行高

worksheet.properties.defaultRowHeight = 20;

设置工作表的默认列宽

worksheet.properties.defaultColWidth = 50;

设置文字样式(行,列,单元格均可设置)

var collectcell = worksheet.getCell(‘A2’);
collectcell.font = { name: ‘Microsoft YaHei’, size: 10, bold: false, color: { argb: “ffffffff” } };

设置背景色(行,列,单元格均可设置)

var collectcell = worksheet.getCell(‘A2’);
collectcell.fill = { type: “pattern”, pattern: “solid”, fgColor: { argb: “ff538dd5” } };

设置内容对齐方式(行,列,单元格均可设置)

var collectcell = worksheet.getCell(‘A2’);
collectcell.alignment = {
top: { style: “thin”, color: { argb: “FF000000” } },
left: { style: “thin”, color: { argb: “FF000000” } },
bottom: { style: “thin”, color: { argb: “FF000000” } },
right: { style: “thin”, color: { argb: “FF000000” } },
}

循环行内的每一个单元格(包括空单元格)

let r_data = ws.getRow(i + rowStart + 1);
// 循环本行插入的每个单元格,然后给单元格设置边框样式(注意,一定要插入数据后,才能循环设置)
r_data.eachCell({ includeEmpty: true }, function (cell, colNumber) {
console.log('Cell ’ + colNumber + ’ = ’ + cell.value);
});

遇见的一些问题:

1. 报错:FileSaver.saveAs is not a function.saveAs is not a function
解决方法: 将 FileSaver.saveAs 改成 window.saveAs 即可(原因是 FileSaver 是全局引用了)

2. 为什么不直接用 wb.xlsx.writeFile
答:因为 wb.xlsx.writeFile 只能 node 用,所以需要用 FileSaver

3. eachCell 为什么会无效(不进入循环)
答:一定要插入数据后,才能循环,没有插入数据的时候是无法进入循环的。

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

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

相关文章

volatile-可见性案例详解

6.3 volatile特性 6.3.1 保证可见性 保证不同线程对某个变量完成操作后结果及时可见&#xff0c;即该共享变量一旦改变所有线程立即可见 不加volatile&#xff0c;没有可见性&#xff0c;程序无法停止 加了volatile&#xff0c;保证可见性&#xff0c;程序可以停止 public…

031-第三代软件开发-屏幕保护

第三代软件开发-屏幕保护 文章目录 第三代软件开发-屏幕保护项目介绍屏幕保护 关键字&#xff1a; Qt、 Qml、 MediaPlayer、 VideoOutput、 function 项目介绍 欢迎来到我们的 QML & C 项目&#xff01;这个项目结合了 QML&#xff08;Qt Meta-Object Language&#…

Rowset Class

Rowset类在PeopleCode中非常常见&#xff0c;以下将Rowset翻译成行集&#xff0c;顾名思义&#xff0c;行的集合 目录 Understanding Rowset Class Shortcut Considerations Data Type of a Rowset Object Scope of a Rowset Object Rowset Class Built-In Functions Row…

SysTick—系统定时器

SysTick 简介 SysTick—系统定时器是属于CM3内核中的一个外设&#xff0c;内嵌在NVIC中。系统定时器是一个24bit 的向下递减的计数器&#xff0c;计数器每计数一次的时间为1/SYSCLK&#xff0c;一般我们设置系统时钟SYSCLK 等于72M。当重装载数值寄存器的值递减到0的时候&#…

SpringBoot+Mybatis 配置多数据源及事务管理

目录 1.多数据源 2.事务配置 项目搭建参考: 从零开始搭建SpringBoot项目_从0搭建springboot项目-CSDN博客 SpringBoot学习笔记(二) 整合redismybatisDubbo-CSDN博客 1.多数据源 添加依赖 <dependencies><dependency><groupId>org.springframework.boot&…

TCP--拥塞控制

大家好&#xff0c;我叫徐锦桐&#xff0c;个人博客地址为www.xujintong.com。平时记录一下学习计算机过程中获取的知识&#xff0c;还有日常折腾的经验&#xff0c;欢迎大家来访。 TCP中另一个重要的点就是拥塞控制&#xff0c;TCP是无私的当它感受到网络拥堵了&#xff0c;就…

字节码进阶之javassist字节码操作类库详解

字节码进阶之javassist字节码操作类库详解 文章目录 前言使用教程添加Javassist依赖库创建和修改类方法拦截创建新的方法 进阶用法创建新的注解创建新的接口创建新的构造器生成动态代理修改方法示例2 前言 Javassist&#xff08;Java programming assistant&#xff09;是一个…

磁盘分区如何分? 电脑磁盘分区免费软件指南!

列出并比较顶级免费磁盘分区管理器软件&#xff0c;以选择适用于 Windows 的最佳分区软件&#xff1a; 系统分区在现代计算机设备中起着非常重要的作用。它们可以存储数据&#xff0c;使系统文件远离用户数据&#xff0c;并在同一台设备上安装多个操作系统。但是&#xff0c;这…

订单正向链路压测

这次压测会对正向链路中的生订单号、生成订单、预支付、支付回调四个接口做压测&#xff0c;其他接口或逆向接口并发要求不高&#xff0c;所以不做压测。 1、100并发压测4核8G&#xff08;初步压测&#xff0c;看代码是否有问题&#xff09; 压测结果&#xff1a;可以看到&am…

网络协议--IP选路

9.1 引言 选路是IP最重要的功能之一。图9-1是IP层处理过程的简单流程。需要进行选路的数据报可以由本地主机产生&#xff0c;也可以由其他主机产生。在后一种情况下&#xff0c;主机必须配置成一个路由器&#xff0c;否则通过网络接口接收到的数据报&#xff0c;如果目的地址不…

python接口自动化测试(单元测试方法)

一、环境搭建 python unittest requests实现http请求的接口自动化Python的优势&#xff1a;语法简洁优美, 功能强大, 标准库跟第三方库灰常强大&#xff0c;建议大家事先了解一下Python的基础;unittest是python的标准测试库&#xff0c;相比于其他测试框架是python目前使用最广…

MySQL -- 库和表的操作

MySQL – 库和表的操作 文章目录 MySQL -- 库和表的操作一、库的操作1.创建数据库2.查看数据库3.删除数据库4.字符集和校验规则5.校验规则对数据库的影响6.修改数据库7.备份和恢复8.查看连接情况 二、表的操作1.创建表2.查看表结构3.修改表4.删除表 一、库的操作 注意&#xf…

蓝桥杯中级题目之组合(c++)

系列文章目录 数位递增数_睡觉觉觉得的博客-CSDN博客拉线开关。_睡觉觉觉得的博客-CSDN博客蓝桥杯中级题目之数字组合&#xff08;c&#xff09;_睡觉觉觉得的博客-CSDN博客 文章目录 系列文章目录前言一、个人名片二、描述三、输入输出以及代码示例1.输入2.输出3.代码示例 总…

muduo异步日志库

文章目录 一、日志库模型1.前端 参考 一、日志库模型 组成部分 muduo日志库由前端和后端组成。 muduo日志库是异步高性能日志库&#xff0c;其性能开销大约是前端每写一条日志消息耗时1.0us~1.6us。 采用双缓冲区&#xff08;double buffering&#xff09;交互技术。基本思…

蛇口街道小区长者服务示范点 ——在家门口“乐享晚年”

2023年9月28日&#xff0c;深圳市南山区蛇口街道创建健康街道行动之“老年肌少症免费筛查”项目走进了海昌社区&#xff0c;为数十位长者开展了系统筛查。在家门口就能够享受到由蛇口医院康复科医生提供的专业服务&#xff0c;这对于小区的老人们来说还是第一次。自今年7月以来…

【红日靶场】vulnstack5-完整渗透过程

系列文章目录 【红日靶场】vulnstack1-完整渗透过程 【红日靶场】vulnstack2-完整渗透过程 【红日靶场】vulnstack3-完整渗透过程 【红日靶场】vulnstack4-完整渗透过程 文章目录 系列文章目录描述虚拟机密码红队思路 一、环境初始化二、开始渗透外网打点上线cs权限提升域信息…

图(graph)的遍历----深度优先(DFS)遍历

目录 前言 深度优先遍历&#xff08;DFS&#xff09; 1.基本概念 2.算法思想 3.二叉树的深度优先遍历&#xff08;例子&#xff09; 图的深度优先遍历 1.图(graph)邻接矩阵的深度优先遍历 思路分析 代码实现 2.图(graph)邻接表的深度优先遍历 思路分析 代码实现 递…

京东数据分析:2023年9月京东洗烘套装品牌销量排行榜!

鲸参谋监测的京东平台9月份洗烘套装市场销售数据已出炉&#xff01; 根据鲸参谋平台的数据显示&#xff0c;今年9月份&#xff0c;京东平台洗烘套装的销量为7100&#xff0c;环比下降约37%&#xff0c;同比增长约87%&#xff1b;销售额为6000万&#xff0c;环比下降约48%&#…

Rust-后端服务调试入坑记

这篇文章收录于Rust 实战专栏。这个专栏中的相关代码来自于我开发的笔记系统。它启动于是2023年的9月14日。相关技术栈目前包括&#xff1a;Rust&#xff0c;Javascript。关注我&#xff0c;我会通过这个项目的开发给大家带来相关实战技术的分享。 如果你关注过我的Rust 实战里…

Elasticsearch实践:ELK+Kafka+Beats对日志收集平台的实现

可以在短时间内搜索和分析大量数据。 Elasticsearch 不仅仅是一个全文搜索引擎&#xff0c;它还提供了分布式的多用户能力&#xff0c;实时的分析&#xff0c;以及对复杂搜索语句的处理能力&#xff0c;使其在众多场景下&#xff0c;如企业搜索&#xff0c;日志和事件数据分析等…