【exceljs】纯前端如何实现Excel导出下载和上传解析?

devtools/2024/10/17 18:26:27/

前段时间写过一篇类似的文章,介绍了sheetjs。最近发现了一个更好用的库ExcelJS,它支持高级的样式自定义,并且使用起来也不复杂。实际上sheetjs也支持高级自定义样式,不过需要使用付费版。

下面对比了Exceljs和Sheetjs:

特性ExcelJSSheetJS (xlsx)
写入样式支持单元格的样式设置(字体、颜色、边框等)不支持样式设置
图表支持不支持不支持
内存效率适合处理较大文件,支持流式写入与读取处理大文件时内存占用较高,需要手动优化
流式操作支持(如流式写入、读取大文件)不支持流式操作,适用于小到中型数据集的处理
社区与文档文档详尽,社区活跃社区活跃,文档相对较简单
适用场景适合需要丰富样式、较大数据集处理的场景适合快速操作小型文件,支持更多文件格式

ExcelJS主要用于Node.js环境,它是一个Node.js库。因此,它的核心功能是为Node.js应用程序提供操作Excel文件的接口。虽然ExcelJS本身是为Node.js设计的,但它也提供了在浏览器端使用的版本。

这里我们主要来介绍浏览器端的使用方式,还是通过下载和上传来演示这个库的常规用法,更多功能可以参考文档:
https://github.com/exceljs/exceljs/blob/master/README_zh.md

前端实现Excel导出下载

先来看下功能演示,如下图把表格中的数据下载到excel文件中
在这里插入图片描述

export const exportExcel = (data: DataType[] ) => {const headerStyle = {font: {name: 'Arial',family: 4,size: 12,bold: true,// color: { argb: 'FF0000' }},fill: {type: 'pattern',pattern: 'solid',// fgColor: { argb: 'FFFF00' },// bgColor: { argb: 'FFFF00' }},alignment: {vertical: 'middle',horizontal: 'center'},border: {top: {style: 'thin', color: {argb: '000000'}},left: {style: 'thin', color: {argb: '000000'}},bottom: {style: 'thin', color: {argb: '000000'}},right: {style: 'thin', color: {argb: '000000'}}}};const headerTitle = ['APP', '名称', '作品数']const workbook = new ExcelJS.Workbook();const ws = workbook.addWorksheet("Sheet1")ws.addRow(headerTitle).eachCell((cell) => {// eslint-disable-next-line @typescript-eslint/ban-ts-comment// @ts-expect-errorcell.style = headerStyle})data.forEach(it=> {ws.addRow(Object.values({app: it.app,name: it.name,works: it.works}))})ws.columns = headerTitle.map((header) => ({header, key: header, width: 20}))workbook.xlsx.writeBuffer().then(buffer => {// 创建 Blob 对象const blob = new Blob([buffer], {type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'});// 创建下载链接const url = window.URL.createObjectURL(blob);const a = document.createElement('a');a.href = url;a.download = `exceljs.xlsx`;a.click();// 清理 URLsetTimeout(() => {window.URL.revokeObjectURL(url);a.remove();}, 100);}).catch(err => console.error('Error creating file:', err));
}

这段代码实现的功能是:

  1. 使用ExcelJS.Workbook()创建一个Workbook对象
  2. 使用addWorksheet("Sheet1")向Workbook中添加一个sheet
  3. 使用addRow方法先加入表头,再使用eachCell为表头单元格设置样式,后面添加数据也是使用这个方法
  4. 最后通过模拟点击a标签下载xlsx

前端实现Excel上传解析

将上面下载的excel文件再次上传解析

在这里插入图片描述

这里使用antd的Upload组件获取到file文件对象,你可以可以使用原生的标签来上传。beforeUpload是上传前调用这个方法, 我们的目的是获取到file对象,没有必要把文件真的上传到服务器,所以返回值为false,表示不再执行后续上传动作了。

<UploadmultipleshowUploadList={false}action="/"beforeUpload={async (file) => {const excelData = await uploadExcel(file);setTableData([...tableData, ...excelData])return false;}}
><Button>上传Excel</Button>
</Upload>

获取到file对象就传递给exceljs来解析文件,代码如下:

export const uploadExcel = async (file: File) => {const arrayBuffer = await file.arrayBuffer()const tableData: DataType[] = [];const workbook = new ExcelJS.Workbook();try {await workbook.xlsx.load(arrayBuffer);// 获取第一个工作表const worksheet = workbook.getWorksheet(1);// 读取工作表中的数据worksheet?.eachRow({includeEmpty: true}, (row, rowNumber) => {console.log(`Row ${rowNumber}:`, row.values);// 去掉表头if (rowNumber > 1) {tableData.push({key: rowNumber.toString(),// eslint-disable-next-line @typescript-eslint/ban-ts-comment// @ts-expect-errorapp: row.values[1].trim(),// eslint-disable-next-line @typescript-eslint/ban-ts-comment// @ts-expect-errorname: row.values[2].trim(),// eslint-disable-next-line @typescript-eslint/ban-ts-comment// @ts-expect-errorworks: row.values[3].trim()})}});} catch (error) {console.error('Error loading workbook:', error);}console.log(tableData);return tableData;
}

下面解释一下这段代码

  1. 使用ExcelJS.Workbook()创建一个workbook对象
  2. 使用workbook.xlsx.load(arrayBuffer)将文件对象解码
  3. workbook.getWorksheet(1)获取到xls文件的第一个sheet
  4. 使用worksheet?.eachRow方法获取到每行与单元格

在线调试

仓库和在线访问:https://stackblitz.com/~/github.com/fullee/exceljs-demo

运行演示命令:

cd exceljs-demo/
npm i
npm run dev

http://www.ppmy.cn/devtools/126527.html

相关文章

10月15日,每日信息差

第一、《哈利・波特与魔法石》在中国内地总票房突破 3 亿元&#xff0c;包括 2002 年首映的 5600 万&#xff0c;2020 年重映的 1.923 亿&#xff0c;以及 2024 年重映的 5170 万。 第二、全国铁路实施新货物列车运行图&#xff0c;增开城际班列至 131 列&#xff0c;多式联运…

跨站请求伪造(CSRF,Cross-Site Request Forgery)

跨站请求伪造&#xff08;CSRF&#xff0c;Cross-Site Request Forgery&#xff09;是一种网络攻击方式&#xff0c;它允许攻击者在用户不知情的情况下&#xff0c;以用户的名义执行非授权的命令。这种攻击利用了用户已经验证的身份和信任关系&#xff0c;来执行恶意操作。 一…

【C#生态园】窥探C#短信发送库:安装配置指南和发送接收短信API概览

探究C#短信发送库&#xff1a;核心功能、使用场景和API概览 前言 随着移动技术的快速发展&#xff0c;短信服务在软件开发中变得越来越重要。为了简化短信发送过程&#xff0c;许多库和API都已经被开发出来&#xff0c;以便于在不同编程语言中进行短信发送操作。本文将重点介…

Android 自定义Toast显示View

1、创建一个tosat显示的布局文件&#xff1a;toast_custom.xml <?xml version"1.0" encoding"utf-8"?> <com.hjq.shape.layout.ShapeLinearLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width&…

数据链路层数据帧格式及网络层IP数据包格式

数据帧格式 前导码&#xff1a;进入物理层之前的缓冲区&#xff0c;包含的是7个字节&#xff08;56比特&#xff09;交替出现的0和1&#xff0c;作用&#xff1a;提醒接受系统有帧到来&#xff0c;并且使它与输入定时同步 帧起始定界符&#xff1a;1字节&#xff08;8比特&…

推荐算法的学习

文章目录 前言1、模型1.1 从本领域模型的发展历史中学习1.1.1 在历史中总结发展规律和趋势1.1.2 发现模型之间的共性&#xff0c;方便记忆 1.2 从其他领域的发展中学习1.2.1 注意力机制1.2.2 残差网络 1.3 实践该怎么办&#xff1f; 2、 特征2.1 数据源的选择与建立2.2 特征构造…

APIJSON的使用

APIJSON是一个用于简化后端接口开发的工具&#xff0c;在Java中可以按照以下步骤使用&#xff1a; 1. 引入依赖 在Java项目中&#xff0c;需要引入APIJSON的相关依赖。如果使用Maven&#xff0c;可以在pom.xml文件中添加以下依赖&#xff1a; <dependency><groupId…

Linux 挂载新磁盘到指定目录

目录 1. 背景2. 创建新的磁盘3. 创建挂载点4. 格式化新磁盘&#xff08;如果尚未格式化&#xff09;5. 挂载新磁盘6. 开机自启&#xff08;可选&#xff09;7. 卸载磁盘 1. 背景 最近需要使用 Linux 搭建一个 NFS 服务器&#xff0c;主要用于 K8S 的日志和配置的持久化。但是考…