前端导出数据到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.rhkb.cn/news/166431.html

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

相关文章

什么是SpringMVC?简单好理解!

1、SpringMVC是什么&#xff1f; SpringMVC是一个基于Java的实现了MVC设计模式的请求驱动类型的轻量级web框架&#xff0c;通过把Model&#xff0c;View&#xff0c;Controller分离&#xff0c;将web层进行职责解耦&#xff0c;把复杂的web应用分成逻辑清晰的几部分。简化开发&…

UE5场景逐渐变亮问题

1、显示 -- 关闭眼部适应 2、项目设置 -- 关闭自动曝光 参考&#xff1a; 虚幻5/UE5 场景亮度逐渐变亮完美解决方法 - 哔哩哔哩

专业修图软件 Affinity Photo 2 mac中文版编辑功能

Affinity Photo for Mac是应用在MacOS上的专业修图软件&#xff0c;支持多种文件格式&#xff0c;包括psD、PDF、SVG、Eps、TIFF、JPEG等。 Affinity Photo mac提供了许多高级图像编辑功能&#xff0c;如无限制的图层、非破坏性操作、高级的选择工具、高级的调整层、HDR合成、全…

使用 PyAudio、语音识别、pyttsx3 和 SerpApi 构建简单的基于 CLI 的语音助手

德米特里祖布☀️ 一、介绍 正如您从标题中看到的&#xff0c;这是一个演示项目&#xff0c;显示了一个非常基本的语音助手脚本&#xff0c;可以根据 Google 搜索结果在终端中回答您的问题。 您可以在 GitHub 存储库中找到完整代码&#xff1a;dimitryzub/serpapi-demo-project…

RT-Thread学习笔记(四):RT-Thread Studio工具使用

RT-Thread Studio工具使用 官网详细资料实用操作1. 查看 RT-Thread RTOS API 文档2.打开已创建的工程3.添加头文件路径4. 如何设置生成hex文件5.新建工程 官网详细资料 RT-Thread Studio 用户手册 实用操作 1. 查看 RT-Thread RTOS API 文档 2.打开已创建的工程 如果打开项目…

Breach 1.0 靶机

Breach 1.0 环境配置 设置 VMware 上的仅主机模式网卡&#xff0c;勾选 DHCP 自动分配 IP&#xff0c;将子网改为 192.168.110.0/24 将靶机和 kali 连接到仅主机网卡 信息搜集 存活检测 详细扫描 后台网页扫描 网页信息搜集 Initech被入侵&#xff0c;董事会投票决定引入…

pytorch nn.Embedding 读取gensim训练好的词/字向量(有例子)

最近在跑深度学习模型&#xff0c;发现Embedding随机性太强导致模型结果有出入&#xff0c;因此考虑固定初始随机向量&#xff0c;既提前训练好词/字向量&#xff0c;不多说上代码&#xff01;&#xff01; 1、利用gensim训练字向量&#xff08;词向量自行修改&#xff09; #…

基于SegFormer的改进语义分割该网络

摘要 场景解析是无人驾驶领域的一个关键任务&#xff0c;但是传统的语义分割网络往往只关注于提取更深层次的图像语义信息而忽略了全局信息对图像分割任务的重要性。另外随着图像在深层次卷积网络中的传递&#xff0c;卷积核天然的滤波作用会使得图像的边缘趋于平滑而丢失细节特…

Visual Studio 2022下载安装的详细步骤-----C语言编辑器

目录 一、介绍 &#xff08;一&#xff09;和其他软件的区别 &#xff08;二&#xff09;介绍编写C语言的编辑器类型 二、下载安装 三、创建与运行第一个C语言程序 &#xff08;一&#xff09;创建项目 &#xff08;二&#xff09;新建文件 &#xff08;三&#xff09…

深度学习---神经网络基础

深度学习概述 机器学习是实现人工智能的一种途径&#xff0c;深度学习是机器学习的一个子集&#xff0c;深度学习是实现机器学习的一种方法。与机器学习算法的主要区别如下图所示&#xff1a; 传统机器学习算术依赖人工设计特征&#xff0c;并进行特征提取&#xff0c;而深度学…

数据结构----算法--五大基本算法(这里没有写分支限界法)和银行家算法

数据结构----算法–五大基本算法&#xff08;这里没有写分支限界法&#xff09;和银行家算法 一.贪心算法 1.什么是贪心算法 在有多个选择的时候不考虑长远的情况&#xff0c;只考虑眼前的这一步&#xff0c;在眼前这一步选择当前的最好的方案 二.分治法 1.分治的概念 分…

公有云厂商---服务对照表

各厂商特点&#xff1a; Compute: Network: Storage: Database: Migration Tool: Identify: WAF: 来源&#xff1a;https://comparecloud.in/

【网络安全 --- xss-labs靶场通关(1-10关)】详细的xss-labs靶场通关思路及技巧讲解,让你对xss漏洞的理解更深刻

靶场安装&#xff1a; 靶场安装请参考以下博客&#xff0c;既详细有提供工具&#xff1a; 【网络安全 --- xss-labs靶场】xss-labs靶场安装详细教程&#xff0c;让你巩固对xss漏洞的理解及绕过技巧和方法&#xff08;提供资源&#xff09;-CSDN博客【网络安全 --- xss-labs通…

嵌入式硬件中常见的100种硬件选型方式

1请列举您知道的电阻、电容、电感品牌&#xff08;最好包括国内、国外品牌&#xff09;。 电阻&#xff1a; 美国&#xff1a;AVX、VISHAY 威世 日本&#xff1a;KOA 兴亚、Kyocera 京瓷、muRata 村田、Panasonic 松下、ROHM 罗姆、susumu、TDK 台湾&#xff1a;LIZ 丽智、PHY…

服务器数据恢复-RAID5中磁盘被踢导致阵列崩溃的服务器数据恢复案例

服务器数据恢复环境&#xff1a; 一台3U的某品牌机架式服务器&#xff0c;Windows server操作系统&#xff0c;100块SAS硬盘组建RAID5阵列。 服务器故障&#xff1a; 服务器有一块硬盘盘的指示灯亮黄灯&#xff0c;这块盘被raid卡踢出后&#xff0c;raid阵列崩溃。 服务器数据…

JavaEE初阶学习:Servlet

1.Servlet 是什么 Servlet 是一种 Java 程序&#xff0c;用于在 Web 服务器上处理客户端请求和响应。Servlet 可以接收来自客户端&#xff08;浏览器、移动应用等&#xff09;的 HTTP 请求&#xff0c;并生成 HTML 页面或其他格式的数据&#xff0c;然后将响应发送回客户端。S…

解决CondaHTTPError HTTP 000 CONNECTION FAILED for url解决方法

解决CondaHTTPError: HTTP 000 CONNECTION FAILED for url解决方法 问题&#xff1a;使用conda install命令安装包提示CondaHTTPError: HTTP 000 CONNECTION FAILED for url 分析&#xff1a;网络连接问题&#xff0c;大概率是网速不行或者源没有换 解决方案&#xff1a;修改国…

C++多态、虚函数、纯虚函数、抽象类

多态的概念 通俗来说&#xff0c;就是多种形态&#xff0c;具体点就是去完成某个行为&#xff0c;当不同的对象去完成时会产生出不同的状态。 举个简单的例子&#xff1a;抢红包&#xff0c;我们每个人都只需要点击一下红包&#xff0c;就会抢到金额。有些人能…

5G学习笔记之5G频谱

参考&#xff1a;《5G NR通信标准》1. 5G频谱 1G和2G移动业务的频段主要在800MHz~900MHz&#xff0c;存在少数在更高或者更低频段&#xff1b;3G和4G的频段主要在450MHz ~ 6GHz&#xff1b;5G主要是410MHz ~ 6GHz&#xff0c;以及24GHz ~ 52GHz。 5G频谱跨度较大&#xff0c;可…

开源贡献难吗?

本文整理自字节跳动 Flink SQL 技术负责人李本超在 CommunityOverCode Asia 2023 上的 Keynote 演讲&#xff0c;李本超根据自己在开源社区的贡献经历&#xff0c;基于他在贡献开源社区过程中的一些小故事和思考&#xff0c;如何克服困难&#xff0c;在开源社区取得突破&#x…