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

news2024/10/22 16:28:16

前段时间写过一篇类似的文章,介绍了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-error
            cell.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();

            // 清理 URL
            setTimeout(() => {
                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,表示不再执行后续上传动作了。

<Upload
    multiple
    showUploadList={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-error
                    app: row.values[1].trim(),
                    // eslint-disable-next-line @typescript-eslint/ban-ts-comment
                    // @ts-expect-error
                    name: row.values[2].trim(),
                    // eslint-disable-next-line @typescript-eslint/ban-ts-comment
                    // @ts-expect-error
                    works: 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.coloradmin.cn/o/2211491.html

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

相关文章

Linux的习题+一道回溯类型的算法题

Linux的习题 Linux环境与版本 1.linux 2.6.* 内核默认支持的文件系统有哪些&#xff1f;[多选] A.ext3 B.ext2 C.ext4 D.xfs E.ufs 正确答案&#xff1a;ABCD A 全称Linux extended file system, extfs,即Linux扩展文件系统&#xff0c;ext2为第二代 D XFS一种高性能的日…

使用频率最高的 opencv 基础绘图操作 - python 实现

以下是 opencv-python 基本操作绘制示例&#xff0c;绘制&#xff1a; 1&#xff09;圆&#xff0c;2&#xff09;矩形&#xff0c;3&#xff09;线段&#xff0c;4&#xff09;文本。 安装 opencv-python pip install opencv-python 在图上绘制圆的操作&#xff0c;示例如…

HCIP-HarmonyOS Application Developer 习题(五)

1、以下哪种原子化布局能力属于自适应变化能力? A. 拉伸 B.占比 C. 隐藏 D.拆行 答案&#xff1a;A 分析&#xff1a;划分为“自适应变化能力”和“自适应布局能力”两类。 其中&#xff0c;自适应变化能力包含了缩放能力和拉伸能力&#xff0c;自适应布局能力包含了隐藏、折…

『Mysql进阶』Mysql explain详解(五)

目录 Explain 介绍 Explain分析示例 explain中的列 1. id 列 2. select_type 列 3. table 列 4. partitions 列 5. type 列 6. possible_keys 列 7. key 列 8. key_len 列 9. ref 列 10. rows 列 11. filtered 列 12. Extra 列 Explain 介绍 EXPLAIN 语句提供有…

Spring学习——SpringAOP

0. IOC思想(DI)1. 关键注解Repositorypublic class DeptDaoImpl1 implements DeptDao{}RepositoryPrimarypublic class DeptDaoImpl2 implements DeptDao{}Servicepublic class DeptServiceImpl implements DeptService{AutowiredQulifier("deptDaoImpl2")private De…

UE5学习笔记24-添加武器弹药

一、给角色的武器添加弹药 1.创建界面&#xff0c;根据笔记23的界面中添加 2.绑定界面控件 UPROPERTY(meta (Bindwidget))UTextBlock* WeaponAmmoAmount;UPROPERTY(meta (Bindwidget))UTextBlock* CarriedAmmoAmount; 3.添加武器类型枚举 3.1创建武器类型枚举头文件 3.2创建文…

C++容器:map

1.铺垫 1.1map和unorder_map&#xff0c;两者的实现思想不同&#xff0c;但是用法是相同的&#xff1b;map的思想是平衡二叉树&#xff1b;unorder_map的思想是哈希&#xff1b; 1.2在现实及做题中&#xff0c;百分之99&#xff0c;都在使用unorder_map&#xff0c;接下来的讲…

2024 第一次周赛

A: 题目大意 骑士每连续 i 天每天会得到 i 个金币&#xff0c;&#xff08;i 1&#xff0c; 2&#xff0c; 3 &#xff0c; …&#xff09;,那么展开看每一天可以得到的金币数&#xff1a;1 2 2 3 3 3 4 4 4 5 5 5 5 5 … 可以发现就是1个1 &#xff0c;2个2, 3个3…,那么我…

P20机型HW睡眠省电-调研

摘要 AI睡眠场景识别 不激进的智能管控 睡眠省电 UI 以前有单独的睡眠开关选项&#xff0c;现在没有了&#xff0c;但是智能充电模式是使用AI睡眠模式 睡眠识别 华为专利上提到的论文《BTP-A Bedtime Predicting Algorithm》 各种事件状态&#xff08;亮灭屏、alarm、主动…

《数字信号处理》学习08-围线积分法(留数法)计算z 逆变换

目录 一&#xff0c;z逆变换相关概念 二&#xff0c;留数定理相关概念 三&#xff0c;习题 一&#xff0c;z逆变换相关概念 接下来开始学习z变换的反变换-z逆变换&#xff08;z反变化&#xff09;。 由象函数 求它的原序列 的过程就称为 逆变换。即 。 求z逆变换…

RTR-Chapter8

第八章 光与颜色 光量辐射度量学光度学色度学使用RGB颜色进行渲染 从场景到屏幕HDR显示编码色调映射色调再现变换曝光 颜色分级 光量 辐射度量学 辐射度量学&#xff08;radiometry&#xff09;研究的是对电磁辐射&#xff08;electromagnetic radiation&#xff09;的测量&am…

linux线程 | 线程的控制(二)

前言&#xff1a; 本节内容是线程的控制部分的第二个小节。 主要是列出我们的线程控制部分的几个细节性问题以及我们的线程分离。这些都是需要大量的代码去进行实验的。所以&#xff0c; 准备好接受新知识的友友们请耐心观看。 现在开始我们的学习吧。 ps:本节内容适合了解线程…

开源情报(OSINT)入门:初学者指南

欢迎来到令人兴奋的开源情报 (OSINT) 世界&#xff01;如果您是该领域的新手&#xff0c;OSINT 就是收集和分析公开信息以获取见解并制作情报产品。 无论您是安全爱好者、记者还是只是对 OSINT 感兴趣&#xff0c;本入门指南都将带您了解基础知识&#xff0c;让您开始第一次&a…

MySQL进阶学习一(2024.10.07版)

2024-10-06 -------------------------------------------------------------------------------------------------------------------------------- 1.一条SQL语句是如何执行的 单进程的多线程模型 MySQL的物理目录 show global variables like "%basedir%"; …

初学Vue(3)(内置指令)

文章目录 十四、内置指令v-textv-htmlv-cloak&#xff08;没有值&#xff09;v-oncev-pre自定义指令一、定义语法二、配置对象中常用的3个问题三、备注 十四、内置指令 回顾&#xff1a; v-bind &#xff1a;单向绑定解析表达式&#xff0c;可简写为 :xxx v-model : 双向数据绑…

HTML快速入门--第一节--五个基本标签

一、网络编程的三大基石 1.1 url 统一资源定位符&#xff1a; 网址:整个互联网中可以唯一且准确的确定一个资源的位置 (url项目外) 网址:https://www.baidu.com/ https://www.baidu.com/ 协议://ip端口/项目名/页面名 协议:交通法规获取资源 ip端口 &#xff08;域名&…

安全企业邮箱优势与局限,密码策略反馈

密码策略是什么呢&#xff1f;如何设置出安全可靠的密码策略呢&#xff1f;企业邮箱安全始于密码策略&#xff0c;包括复杂性、长度、更新频率、重用限制和两步验证。实施需全员培训、密码管理工具、审计与监控。一文为你详细介绍密码策略。 一、如何设置好的密码策略&#xff…

【JavaScript】JavaScript开篇基础(3)

1.❤️❤️前言~&#x1f973;&#x1f389;&#x1f389;&#x1f389; Hello, Hello~ 亲爱的朋友们&#x1f44b;&#x1f44b;&#xff0c;这里是E绵绵呀✍️✍️。 如果你喜欢这篇文章&#xff0c;请别吝啬你的点赞❤️❤️和收藏&#x1f4d6;&#x1f4d6;。如果你对我的…

【微信小程序_11_全局配置】

摘要:本文介绍了微信小程序全局配置文件 app.json 中的常用配置项,重点阐述了 window 节点的各项配置,包括导航栏标题文字、背景色、标题颜色,窗口背景色、下拉刷新样式以及上拉触底距离等。通过这些配置可实现小程序窗口外观的个性化设置,提升用户体验。 微信小程序_11_全…

总看别人写贪吃蛇,自己也来写一个吧

贪吃蛇是一个流行度非常高的游戏&#xff0c;玩法十分简单&#xff0c;从最初的方块机上就有这个游戏了&#xff0c;后来出现的手机中也是加入了这个游戏&#xff0c;无聊的时候可以打发时间玩一会。这个游戏可谓是非常的简单&#xff0c;容易上手&#xff0c;所以直到现在&…