【日常记录】【插件】excel.js 的使用

文章目录

    • 1. 引言
    • 2. excel.js
      • 2.1 创建工作簿和工作表
      • 2.2 excel文件的导出
      • 2.3 excel文件的导入
      • 2.4 列
      • 2.5 行
      • 2.6 添加行
      • 2.7 单元格
      • 2.8 给总价列设置自动计算(除表头行)
    • 3. 总结
    • 参考链接

1. 引言

前端导出excel文件常用库一般是 excel.jsxlsx.js

xlsx.js 导出数据确实方便,但是处理样式不大好处理,需要配合 xlsx-style 来处理样式问题,比较麻烦了

2. excel.js

npm 安装方式

npm install exceljs

浏览器端 安装方式

<script src="https://cdn.bootcdn.net/ajax/libs/exceljs/4.4.0/exceljs.js"></script>

2.1 创建工作簿和工作表

要先创建一个工作簿,然后才能创建工作表

const workbook = new ExcelJS.Workbook(); // 创建工作簿const worksheet = workbook.addWorksheet("导入数据明细", { properties: { tabColor: { argb: 'FFC0000' } } }); // 创建一个工作表

在这里插入图片描述

wps打开就是这个样子, 一般不会设置这个 工作表的其他属性,最常用的还是直接创建一个工作表和设置 冻结行/列,这俩个操作更为常见

冻结第一行,列不做处理,代码如下

    worksheet.views = [{state: 'frozen',ySplit: 1,}];

在这里插入图片描述

2.2 excel文件的导出

官方提供了三种方式,最常用的是 写入 buffer

第一种:写入文件

// 写入文件
const workbook = createAndFillWorkbook();
await workbook.xlsx.writeFile(filename);

在这里插入图片描述

这种方式,其实是调用了 node的fs 模块 ,如若在浏览器环境直接调用的话,会报错

第二种方式:写入流

await workbook.xlsx.write(stream);

这种方式目前用的比较少,也是依赖于node 环境

第三种方式:写入buffer

// 写入 buffer
const buffer = await workbook.xlsx.writeBuffer();

这种一般比较多见

  1. 写入 buffer ,配合 FileSaver 库,进行导出文件
  2. 用原生 js 方式把 blob转化成一个链接,进行导出
    workbook.xlsx.writeBuffer().then((buffer) => {const blob = new Blob([buffer], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });saveAs(blob, "导出excek.xlsx")})
    workbook.xlsx.writeBuffer().then((buffer) => {const blob = new Blob([buffer], {type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",});let aEl = document.createElement("a");aEl.style = "display: none";aEl.download = `测试excel导出${new Date().getTime()}.xlsx`;aEl.href = window.URL.createObjectURL(blob);// 创建blob 文件链接document.body.appendChild(aEl);aEl.click();document.body.removeChild(aEl);window.URL.revokeObjectURL(aEl.href); // 销毁链接}).catch((err) => {console.error(err)});

2.3 excel文件的导入

比如说,导入内容为这样的一个excel文件

在这里插入图片描述

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head><body><input type="file" name="" id="file"><script src="https://cdn.bootcdn.net/ajax/libs/exceljs/4.3.0/exceljs.min.js"></script><script>document.querySelector('#file').addEventListener("change", function (e) {const file = e.target.files[0];if (file) {const reader = new FileReader();reader.onload = function (e) {const workbook = new ExcelJS.Workbook();let importData = [];workbook.xlsx.load(e.target.result).then(async (res) => {const worksheet = workbook.getWorksheet(1);let importData = [];worksheet.eachRow({includeEmpty: true, // 包含空行},function (row, rowNumber) {console.log(row, rowNumber, row.values);importData.push(row.values)});console.log("所有行", importData);}).catch((err) => {console.log("err", err);});};reader.readAsArrayBuffer(file);}});</script>
</body></html>

这里的 row,rowNumber,row.values 打印内容如下

在这里插入图片描述

这里要特别注意的是,在 excel 文件里面,三行四列 但这每一行的值,数组长度是5,因为便于取数,这个数组的第一项是null,因为数组第一项索引是0,所以,索引1 才是 这一行第一列的值

2.4 列

    worksheet.columns = [{header: "序号",key: "Index",width: 7,},{header: "单价",key: "Price",}, {header: "数量",key: "Quantity"}, {header: "总价",key: "TotalPrice"}]
  • header:列的标题
  • key:列表ID
  • width:列的宽度,这个宽度和像素不一样,需要自己调试

导出的效果如下

在这里插入图片描述

官网还列举了其他的案例
最常用的还是 设置列

// 添加列标题并定义列键和宽度
// 注意:这些列结构仅是构建工作簿的方便之处,除了列宽之外,它们不会完全保留。
worksheet.columns = [{ header: 'Id', key: 'id', width: 10 },{ header: 'Name', key: 'name', width: 32 },{ header: 'D.O.B.', key: 'DOB', width: 10, outlineLevel: 1 }
];// 通过键,字母和基于1的列号访问单个列
const idCol = worksheet.getColumn('id');
const nameCol = worksheet.getColumn('B');
const dobCol = worksheet.getColumn(3);// 设置列属性// 注意:将覆盖 C1 单元格值
dobCol.header = 'Date of Birth';// 注意:这将覆盖 C1:C2 单元格值
dobCol.header = ['Date of Birth', 'A.K.A. D.O.B.'];// 从现在开始,此列将以 “dob” 而不是 “DOB” 建立索引
dobCol.key = 'dob';dobCol.width = 15;// 如果需要,隐藏列
dobCol.hidden = true;// 为列设置大纲级别
worksheet.getColumn(4).outlineLevel = 0;
worksheet.getColumn(5).outlineLevel = 1;// 列支持一个只读字段,以指示基于 `OutlineLevel` 的折叠状态
expect(worksheet.getColumn(4).collapsed).to.equal(false);
expect(worksheet.getColumn(5).collapsed).to.equal(true);// 遍历此列中的所有当前单元格
dobCol.eachCell(function(cell, rowNumber) {// ...
});// 遍历此列中的所有当前单元格,包括空单元格
dobCol.eachCell({ includeEmpty: true }, function(cell, rowNumber) {// ...
});// 添加一列新值
worksheet.getColumn(6).values = [1,2,3,4,5];// 添加稀疏列值
worksheet.getColumn(7).values = [,,2,3,,5,,7,,,,11];// 剪切一列或多列(右边的列向左移动)
// 如果定义了列属性,则会相应地对其进行切割或移动
// 已知问题:如果拼接导致任何合并的单元格移动,结果可能是不可预测的
worksheet.spliceColumns(3,2);// 删除一列,再插入两列。
// 注意:第4列及以上的列将右移1列。
// 另外:如果工作表中的行数多于列插入项中的值,则行将仍然被插入,就好像值存在一样。
const newCol3Values = [1,2,3,4,5];
const newCol4Values = ['one', 'two', 'three', 'four', 'five'];
worksheet.spliceColumns(3, 1, newCol3Values, newCol4Values);

2.5 行

这个地方,一般常用的是,读取行读取整个工作表的行/读取指定行的值

官方的例子如下

// 获取一个行对象。如果尚不存在,则将返回一个新的空对象
const row = worksheet.getRow(5);// Get multiple row objects. If it doesn't already exist, new empty ones will be returned
const rows = worksheet.getRows(5, 2); // start, length (>0, else undefined is returned)// 获取工作表中的最后一个可编辑行(如果没有,则为 `undefined`)
const row = worksheet.lastRow;// 设置特定的行高
row.height = 42.5;// 隐藏行
row.hidden = true;// 为行设置大纲级别
worksheet.getRow(4).outlineLevel = 0;
worksheet.getRow(5).outlineLevel = 1;// 行支持一个只读字段,以指示基于 `OutlineLevel` 的折叠状态
expect(worksheet.getRow(4).collapsed).to.equal(false);
expect(worksheet.getRow(5).collapsed).to.equal(true);row.getCell(1).value = 5; // A5 的值设置为5
row.getCell('name').value = 'Zeb'; // B5 的值设置为 “Zeb” - 假设第2列仍按名称键入
row.getCell('C').value = new Date(); // C5 的值设置为当前时间// 获取行并作为稀疏数组返回
// 注意:接口更改:worksheet.getRow(4) ==> worksheet.getRow(4).values
row = worksheet.getRow(4).values;
expect(row[5]).toEqual('Kyle');// 通过连续数组分配行值(其中数组元素 0 具有值)
row.values = [1,2,3];
expect(row.getCell(1).value).toEqual(1);
expect(row.getCell(2).value).toEqual(2);
expect(row.getCell(3).value).toEqual(3);// 通过稀疏数组分配行值(其中数组元素 0 为 `undefined`)
const values = []
values[5] = 7;
values[10] = 'Hello, World!';
row.values = values;
expect(row.getCell(1).value).toBeNull();
expect(row.getCell(5).value).toEqual(7);
expect(row.getCell(10).value).toEqual('Hello, World!');// 使用列键按对象分配行值
row.values = {id: 13,name: 'Thing 1',dob: new Date()
};// 在该行下方插入一个分页符
row.addPageBreak();// 遍历工作表中具有值的所有行
worksheet.eachRow(function(row, rowNumber) {console.log('Row ' + rowNumber + ' = ' + JSON.stringify(row.values));
});// 遍历工作表中的所有行(包括空行)
worksheet.eachRow({ includeEmpty: true }, function(row, rowNumber) {console.log('Row ' + rowNumber + ' = ' + JSON.stringify(row.values));
});// 连续遍历所有非空单元格
row.eachCell(function(cell, colNumber) {console.log('Cell ' + colNumber + ' = ' + cell.value);
});// 遍历一行中的所有单元格(包括空单元格)
row.eachCell({ includeEmpty: true }, function(cell, colNumber) {console.log('Cell ' + colNumber + ' = ' + cell.value);
});// 提交给流一个完成的行
row.commit();// 行尺寸
const rowSize = row.cellCount;
const numValues = row.actualCellCount;

2.6 添加行

这个操作,在导出数据的最为常见

    worksheet.addRow({Index: 1,Price: 9.9,Quantity: 1,TotalPrice: 1})worksheet.insertRow(2, {Index: 2,Price: 3.8,Quantity: 1,TotalPrice: 1})

首先是添加了一行,这一行在 Excel 中,行数应该是2 ,但是后面又插入了一行,并且指定了行数为2, 那么第一行,就得往下移,效果如下

在这里插入图片描述

官方代码

// Add a couple of Rows by key-value, after the last current row, using the column keys
worksheet.addRow({id: 1, name: 'John Doe', dob: new Date(1970,1,1)});
worksheet.addRow({id: 2, name: 'Jane Doe', dob: new Date(1965,1,7)});// Add a row by contiguous Array (assign to columns A, B & C)
worksheet.addRow([3, 'Sam', new Date()]);// Add a row by sparse Array (assign to columns A, E & I)
const rowValues = [];
rowValues[1] = 4;
rowValues[5] = 'Kyle';
rowValues[9] = new Date();
worksheet.addRow(rowValues);// Add a row with inherited style
// This new row will have same style as last row
// And return as row object
const newRow = worksheet.addRow(rowValues, 'i');// Add an array of rows
const rows = [[5,'Bob',new Date()], // row by array{id:6, name: 'Barbara', dob: new Date()}
];
// add new rows and return them as array of row objects
const newRows = worksheet.addRows(rows);// Add an array of rows with inherited style
// These new rows will have same styles as last row
// and return them as array of row objects
const newRowsStyled = worksheet.addRows(rows, 'i');

2.7 单元格

如若要是对第一行的列,进行美化怎么处理呢?

  1. 先获取到第一行
  2. 使用 Excel.js 的 行遍历单元格方法
     const headerRow = worksheet.getRow(1);// 遍历一行中的所有单元格(包括空单元格)headerRow.eachCell({includeEmpty: true}, function (cell, colNumber) {console.log(cell, colNumber);// getCell 传入一个单元格地址,就可以获取到这个单元格,然后对这个单元格进行操作worksheet.getCell(cell._address).font = {size: 16,// 字体大小bold: true // 加粗}worksheet.getCell(cell._address).alignment = {vertical: 'middle', // 垂直方向剧中horizontal: 'center' // 水平方向剧中}});

下面这个图,就是每次遍历单元格的时候,第一个参数值,里面有一个 _address 存放的就是当前遍历到的单元格的地址

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

2.8 给总价列设置自动计算(除表头行)

在excel文档中,是可以使用 函数的,同样在excel.js库中也可以使用

    console.log('当前sheet总行数', worksheet.rowCount);for (let i = 2; i <= worksheet.rowCount; i++) {worksheet.getCell(`D${i}`).value = {formula: `PRODUCT(B${i},C${i})`};console.log(worksheet.getCell(`D${i}`));}

下载下来excel 发现,这一个单元格,就不是单纯的数字了,而是一个函数,这个函数是表示的意思是,这个D2单元格 = B3 * C3。就是说,当 B3 / C3 单元格的值发现变化的时候,他就会重新计算,类似于vue 的 计算属性

在这里插入图片描述

3. 总结

其实 excel.js 文档里面,还有很多操作,现在只是列举了一些简单的操作,其他的可以观看文档学习一下,文档很清晰

参考链接

  • excel.js gitee 地址
  • FileSaver.js GitHub地址

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

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

相关文章

超时导致SparkContext构造失败的问题探究

文章目录 1.前言2. 基于事故现场对问题进行分析2.1 日志分析2.2 单独测试Topology代码试图重现问题 3. 源码解析3.1 Client模式和Cluster模式下客户端的提交和启动过程客户端提交时在两种模式下的处理逻辑ApplicationMaster启动时在两种模式下的处理逻辑 3.2 两种模式下的下层角…

Python和C++骨髓细胞进化解析数学模型

&#x1f3af;要点 &#x1f3af; 数学模型邻接矩阵及其相关的转移概率 | &#x1f3af;蒙特卡罗模拟进化动力学 | &#x1f3af;细胞进化交叉图族概率 | &#x1f3af;进化图模型及其数学因子 | &#x1f3af;混合图模式对进化概率的影响 | &#x1f3af;造血干细胞群体的空间…

7.13实训日志

上午 学习网络安全的过程中&#xff0c;我们深入了解了网络的不同层面和技术&#xff0c;从表层网络到深网再到暗网&#xff0c;以及涉及的产业分类和技术工具。这些知识不仅帮助我们理解网络的复杂性&#xff0c;还揭示了如何应对和防范各种网络威胁。 首先&#xff0c;我们…

Qt Style Sheets-入门

Qt 样式表是一种强大的机制&#xff0c;允许您自定义小部件的外观&#xff0c;这是在通过子类化QStyle已经可行的基础上的补充。Qt 样式表的概念、术语和语法在很大程度上受到 HTML级联样式表 (CSS)的启发&#xff0c;但适用于小部件的世界。 概述 样式表是文本规范&#xff0…

【眼疾病识别】图像识别+深度学习技术+人工智能+卷积神经网络算法+计算机课设+Python+TensorFlow

一、项目介绍 眼疾识别系统&#xff0c;使用Python作为主要编程语言进行开发&#xff0c;基于深度学习等技术使用TensorFlow搭建ResNet50卷积神经网络算法&#xff0c;通过对眼疾图片4种数据集进行训练&#xff08;‘白内障’, ‘糖尿病性视网膜病变’, ‘青光眼’, ‘正常’&…

C++动态内存的管理

今天来分享C动态内存管理相关知识&#xff0c;闲言勿谈&#xff0c;直接上干货。 1. 动态内存的开辟和销毁(new和delete) (1)前置知识&#xff1a;我们知道c语言有malloc和calloc和realloc三个函数可以进行动态的开辟内存&#xff0c;那么它们有什么区别呢&#xff1f;首先是…

IntelliJ IDEA 2024.1 最新变化 附问卷调查 AI

IntelliJ IDEA 2024.1 最新变化 问卷调查项目在线AI IntelliJ IDEA 2024.1 最新变化关键亮点全行代码补全 Ultimate对 Java 22 功能的支持新终端 Beta编辑器中的粘性行 AI AssistantAI Assistant 改进 UltimateAI Assistant 中针对 Java 和 Kotlin 的改进代码高亮显示 Ultimate…

【STM32嵌入式系统设计与开发---拓展】——1_9_1上拉输入和下拉输入

在使用GPIO引脚时&#xff0c;上拉输入和下拉输入的选择取决于外部电路的特性和应用需求。以下是它们各自的应用场景&#xff1a; 1、上拉输入&#xff08;Pull-up Input&#xff09; 用途: 当默认状态需要为高电平时。 避免引脚悬空&#xff08;floating&#xff09;导致的…

安卓onNewIntent 什么时候执行

一.详细介绍 onNewIntent 方法 onNewIntent 是 Android 中 Activity 生命周期的一部分。它在特定情况下被调用&#xff0c;主要用于处理新的 Intent&#xff0c;而不是创建新的 Activity 实例。详细介绍如下&#xff1a; 使用场景 singleTop 启动模式&#xff1a; 如果一个 Ac…

《云原生安全攻防》-- 容器攻击案例:Docker容器逃逸

当攻击者获得一个容器环境的shell权限时&#xff0c;攻击者往往会尝试进行容器逃逸&#xff0c;利用容器环境中的错误配置或是漏洞问题&#xff0c;从容器成功逃逸到宿主机&#xff0c;从而获取到更高的访问权限。 在本节课程中&#xff0c;我们将详细介绍一些常见的容器逃逸方…

构建实时银行应用程序:英国金融机构 Nationwide 为何选择 MongoDB Atlas

Nationwide Building Society 超过135年的互助合作 Nationwide Building Society&#xff08;以下简称“Nationwide”&#xff09; 是一家英国金融服务提供商&#xff0c;拥有超过 1500 万名会员&#xff0c;是全球最大的建房互助会。 Nationwide 的故事可以追溯到 1884 年&am…

论文翻译:Large Language Models for Education: A Survey

目录 大型语言模型在教育领域的应用&#xff1a;一项综述摘要1 引言2. 教育中的LLM特征2.1. LLMs的特征2.2 教育的特征2.2.1 教育发展过程 低进入门槛。2.2.2. 对教师的影响2.2.3 教育挑战 2.3 LLMEdu的特征2.3.1 "LLMs 教育"的具体体现2.3.2 "LLMs 教育"…

BUUCTF逆向wp [HDCTF2019]Maze

第一步 查壳&#xff0c;本题是32位&#xff0c;有壳&#xff0c;进行脱壳。 第二步 这里的 jnz 指令会实现一个跳转&#xff0c;并且下面的0EC85D78Bh被标红了&#xff0c;应该是一个不存在的地址&#xff0c;这些东西就会导致IDA无法正常反汇编出原始代码&#xff0c;也称…

【Linux】将IDEA项目部署到云服务器上,让其成为后台进程(保姆级教学,满满的干货~~)

目录 部署项目到云服务器什么是部署一、 创建MySQL数据库二、 修改idea配置项三、 数据打包四、 部署云服务器五、开放端口号六 、 验证程序 部署项目到云服务器 什么是部署 ⼯作中涉及到的"环境" 开发环境:开发⼈员写代码⽤的机器.测试环境:测试⼈员测试程序使⽤…

离线语音识别芯片在智能生活中的应用

离线语音识别芯片&#xff0c;这一技术正逐渐渗透到我们日常生活的每一个角落&#xff0c;为众多产品带来前所未有的智能体验。它能够应用到多种产品中&#xff0c;‌包括但不限于&#xff1a;‌ 1、智能音箱&#xff1a;‌语音识别芯片作为智能音箱的核心&#xff0c;‌使用户…

自动驾驶车道线检测系列—3D-LaneNet: End-to-End 3D Multiple Lane Detection

文章目录 1. 摘要概述2. 背景介绍3. 方法3.1 俯视图投影3.2 网络结构3.2.1 投影变换层3.2.2 投影变换层3.2.3 道路投影预测分支 3.3 车道预测头3.4 训练和真实值关联 4. 实验4.1 合成 3D 车道数据集4.2 真实世界 3D 车道数据集4.3 评估结果4.4 评估图像仅车道检测 5. 总结和讨论…

Centos7 安装私有 Gitlab

在 CentOS 7上&#xff0c;下面的命令也会在系统防火墙中打开 HTTP、HTTPS 和 SSH 访问。这是一个可选步骤&#xff0c;如果您打算仅从本地网络访问极狐GitLab&#xff0c;则可以跳过它。 sudo yum install -y curl policycoreutils-python openssh-server perl sudo systemct…

算法 —— 快速幂

目录 P1045 [NOIP2003 普及组] 麦森数 P1226 【模板】快速幂 原理I 原理II P1226 代码解析 P1045 代码解析 P1045 [NOIP2003 普及组] 麦森数 本题来自洛谷&#xff1a;P1045 [NOIP2003 普及组] 麦森数&#xff0c;根据题意&#xff0c;我们可以看到本题需要计算最少2的1…

Docker的数据管理和网络通信

目录 一、Docker 的数据管理 1&#xff0e;数据卷 2&#xff0e;数据卷容器 二、端口映射 三、容器互联&#xff08;使用centos镜像&#xff09; 四、*Docker 镜像的创建 1&#xff0e;基于现有镜像创建 2&#xff0e;基于本地模板创建 3&#xff0e;基于Dockerfile 创…

SwiftUI中App启动入口分析,以及视图和App生命周期介绍

App入口分析 新创建的swiftui项目中我们应该先要了解一下app的入口函数在哪里,并了解大概的含义。 @main:标记应用程序的入口。 App 协议:SwiftUI 应用程序的入口点。 Scene:表示应用程序的一个视图层级,通常是 WindowGroup,表示主窗口的内容。 Scene讲解 Scene 表示…