EasyExcel 处理 Excel

embedded/2024/9/25 2:09:22/

序言

本文介绍在日常的开发中,如何使用 EasyExcel 高效处理 Excel。

EasyExcel__2">一、EasyExcel 是什么

EasyExcel 是阿里巴巴开源的一个 Java Excel 操作类库,它基于 Apache POI 封装了简单易用的 API,使得我们能够方便地读取、写入 Excel 文件。EasyExcel 支持读写 Excel 的各种操作,包括读取 Excel 内容、写入 Excel 内容、大数据量导出、模板导出等功能。

上图是 EasyExcel 官方给出的 16M 内存 23 秒读取 75M (46W 行 25 列) 的 Excel(3.2.1+版本) 测试效果。我们可以看出 EasyExcel 具有以下特点:

  1. 高性能
  2. 低内存占用

EasyExcel__Excel_11">二、EasyExcel 读取 Excel

场景假设:我们需要读取下图 Excel 文件中的内容

image.png

2.1 引入依赖

<dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.3.1</version>
</dependency>

2.2 编写实体类

java">@Data
public class ExcelData {// 编号private int id;// 姓名private String name;// 年龄private int age;
}

EasyExcel__Excel_35">2.3 EasyExcel 读取 Excel

java">// 读取的 Excel 路径
String filePath = "test.xlsx";
// 接收读取的数据
List<ExcelData> dataList = new ArrayList<>();// 读取数据并将数据放入 dataList
// read() 方法一共三个参数
// 第一个参数是文件路径
// 第二个参数是指定接收数据的实体类
// 第三个参数是一个 ReadListener,用于处理读取到数据之后需要做出的动作
// (此处是将读取到的数据放入 dataList 中)
EasyExcel.read(filePath, ExcelData.class, new PageReadListener<ExcelData>(dataList::addAll))
// sheet() 方法表示需要读取的 sheet,默认是第一个 sheet
// doRead() 方法表示正式执行读取操作
.sheet().doRead();// 打印读取的结果
dataList.forEach(System.out::println);

读取效果:

image.png

EasyExcel__Excel_59">三、EasyExcel 写入 Excel

场景假设:我们现在需要将如下数据写入到 Excel 中

编号姓名年龄
1zs10
2ls11
3ww12
4tq13
5zl14

3.1 定义数据实体类

java">@Data
public class ExcelData {@ExcelProperty("编号")private int id;@ExcelProperty("姓名")private String name;@ExcelProperty("年龄")private int age;
}

EasyExcel__Excel_82">3.2 EasyExcel 写入 Excel

java">// 模拟数据
List<ExcelData> dataList = Arrays.asList(new ExcelData(1, "zs", 10),new ExcelData(2, "ls", 11),new ExcelData(3, "ww", 12),new ExcelData(4, "tq", 13),new ExcelData(5, "zl", 14)
);// 定义输出路径
String outPath = "out.xlsx";// 通过 EasyExcel 写入到 Excel
// write() 方法有两个参数
// 第一个参数是输出路径
// 第二个参数是写出数据的实体类
EasyExcel.write(outPath, ExcelData.class)
// sheet() 方法,可以指定 sheet 的名称
.sheet("导出数据")
// doWrite() 方法,执行导出
.doWrite(dataList);

写入效果:

image.png

EasyExcel__109">四、EasyExcel 高级读

4.1 读取额外信息

java">// 读取路径
String filePath = "test.xlsx";
// 存放读取的内容
List<ExcelData> dataList = new ArrayList<>();// 读取
EasyExcel.read(filePath, ExcelData.class, new PageReadListener<ExcelData>(dataList::addAll) {// 重写这个方法,根据具体业务编写业务规则@Overridepublic void extra(CellExtra extra, AnalysisContext context) {switch (extra.getType()) {case COMMENT:System.out.println("执行注释的处理逻辑");break;case HYPERLINK:System.out.println("执行超链接的处理逻辑");break;case MERGE:System.out.println("执行合并单元格的处理逻辑");break;}}
})
// 读取批注
.extraRead(CellExtraTypeEnum.COMMENT)
// 读取超链接
.extraRead(CellExtraTypeEnum.HYPERLINK)
// 读取合并单元格
.extraRead(CellExtraTypeEnum.MERGE)
.sheet().doRead();

4.2 读取多个 sheet

java">String filePath = "test.xlsx";
List<ExcelData> dataList = new ArrayList<>();// 获取 ExcelReader
try (ExcelReader excelReader = EasyExcel.read(filePath).build()) {// 读取第一个 sheetReadSheet sheet1 = EasyExcel.readSheet(0).head(ExcelData.class).registerReadListener(new PageReadListener<ExcelData>(dataList::addAll)).build();// 读取第二个 sheetReadSheet sheet2 = EasyExcel.readSheet(1).head(ExcelData.class).registerReadListener(new PageReadListener<ExcelData>(dataList::addAll)).build();// 执行真正的读取操作excelReader.read(sheet1, sheet2);
}

EasyExcel__167">五、EasyExcel 模板填充

image.png

如上图所示,有时我们需要导出具有格式的 Excel 文件。如果采用普通的写入,处理格式比较麻烦,EasyExcel 提供了模板填充的方式写入。

5.1 定义模板

image.png

5.2 定义实体类

java">@Data
@NoArgsConstructor
@AllArgsConstructor
public class Score {private String name;private int chinese;private int math;private int english;
}

5.3 模板填充

java">// 模拟数据
List<Score> dataList = Arrays.asList(new Score("zs", 90, 89, 77),new Score("ls", 91, 90, 78),new Score("ww", 92, 91, 79),new Score("tq", 93, 92, 80),new Score("zl", 94, 93, 81)
);// 定义输出路径
String outPath = "templateOut.xlsx";
// 定义模板路径
String templatePath = "template.xlsx";
// 输出路径
EasyExcel.write(outPath)
// withTemplate() 方法指定使用的模板路径
.withTemplate(templatePath)
// sheet() 方法默认使用模板的第一个 sheet
.sheet()
// doFill() 方法执行填充
.doFill(dataList);

填充效果:

image.png

六、监听器

回顾一下之前使用 EasyExcel 读:

java">// 第三个参数是一个 ReadListener 对象
EasyExcel.read(filePath, ExcelData.class, new PageReadListener<ExcelData>(dataList::addAll))
.sheet().doRead();

PageReadListener 是 EasyExcel 官方提供的一个 ReadListener。该 ReadListener 会按照每读 100 条的频率处理数据。数据的具体处理逻辑交由开发人员,例如:我们使用 dataList::addAll 将数据添加到 dataList。所以,ReadListener 是 EasyExcel 提供给开发人员进行数据处理的。

image.png

以上是 EasyExcel 提供的 ReadListener,这些 ReadListener 应用于不同的使用场景,具体使用方法可参考官方文档。

七、FAQ

EasyExcel 是非常强大的 Excel 处理工具,尤其是在性能和内存占用方面。如果在开发过程中,有其他特殊需求大家可以参考官方文档寻找解决方案哦。

往期推荐

  1. 实体映射解决方案-MapStruct
  2. 动态切换数据源的最佳实践
  3. Gateway
  4. 缓存神器-JetCache
  5. Mybatis 缓存机制
  6. 为什么 MySQL 单表数据量最好别超过 2000w
  7. IoC 思想简单而深邃
  8. ThreadLocal

http://www.ppmy.cn/embedded/30094.html

相关文章

[C++基础学习]----05-函数详解

前言 在学习C的基础阶段&#xff0c;函数是一个非常重要的概念。函数是用来完成特定任务的一段代码&#xff0c;它可以被多次调用&#xff0c;并且可以接受参数和返回值。 正文 01-函数简介 函数的定义&#xff1a; 在C中&#xff0c;函数的定义通常包括函数的返回类…

python 11Pandas数据可视化实验

实验目的&#xff1a; 学会使用Pandas操作数据集&#xff0c;并进行可视化。 数据集描述&#xff1a; 该数据集是CNKI中与“中药毒理反应”相关的文献信息&#xff0c;包含文章题目、作者、来源&#xff08;出版社&#xff09;、摘要、发表时间等信息。 实验要求&#xff1…

大模型常用的预训练数据集

文章目录 通用网页数据中文网页数据书籍维基百科代码混合型数据集 与早期的预训练语言模型相比&#xff0c;大语言模型需要更多的训练数据&#xff0c;这些数据需要涵盖广泛的内容范围。多领域、多源化的训练数据可以帮助大模型更加全面地学习真实世界的语言与知识&#xff0c;…

Vue 组件的三大组成部分

Vue 组件通常由三大组成部分构成&#xff1a;模板&#xff08;Template&#xff09;、脚本&#xff08;Script&#xff09;、样式&#xff08;Style&#xff09; 模板部分是组件的 HTML 结构&#xff0c;它定义了组件的外观和布局。Vue 使用基于 HTML 的模板语法来声明组件的模…

Microsoft Universal Print 与 SAP 集成教程

引言 从 SAP 环境打印是许多客户的要求。例如数据列表打印、批量打印或标签打印。此类生产和批量打印方案通常使用专用硬件、驱动程序和打印解决方案来解决。 Microsoft Universal Print 是一种基于云的打印解决方案&#xff0c;它允许组织以集中化的方式管理打印机和打印机驱…

踏上R语言之旅:解锁数据世界的神秘密码(四)

文章目录 前言一、多元线性回归1.多元线性回归模型的建立2.多元线性回归模型的检验 二、多元线性相关分析1.矩阵相关分析2.复相关分析 三、回归变量的选择方法1.变量选择准则2.变量选择的常用准则3.逐步回归分析 总结 前言 回归分析研究的主要对象是客观事物变量间的统计关系。…

数字旅游以科技创新为动力:推动旅游服务的智能化、网络化和个性化发展,满足游客日益增长的多元化、个性化需求

目录 一、引言 二、科技创新推动旅游服务智能化发展 1、智能化技术的引入与应用 2、智能化提升旅游服务效率与质量 三、科技创新推动旅游服务网络化发展 1、网络化平台的构建与运营 2、网络化拓宽旅游服务渠道与范围 四、科技创新推动旅游服务个性化发展 1、个性化需求…

boost::asio::ip::tcp::resolver async_resolve异步解析

boost::asio::ip::tcp::resolver::async_resolve 是一个异步解析函数&#xff0c;用于将主机名和服务名转换为端点&#xff08;通常是 IP 地址和端口号&#xff09;。 以下是一个简单的使用示例&#xff1a; #include <boost/asio.hpp> #include <iostream>void …