总结一下常见的EasyExcel面试题

说一下你了解的POI和EasyExcel

POI(Poor Obfuscation Implementation):它是 Apache 软件基金会的一个开源项目,为 Java 程序提供了读写 Microsoft Office 格式文件的功能,支持如 Excel、Word、PowerPoint 等多种文件格式,是 Java 操作 Office 文档的基础工具,发展历史悠久,功能强大且全面

EasyExcel :是阿里巴巴开源的一个基于 POI 进行二次封装的轻量级 Excel 处理框架 ,主要专注于 Excel 文件的读写操作,简化了 POI 的操作流程


EasyExcel对比POI

功能丰富度

POI :POI 是一个底层的 Java 操作 Excel 的工具包,在进行读写操作时,需要手动处理文件流、解析器、工作表、行和单元格等多个元素

以读取文件为例,需要创建工作簿对象、获取工作表 、遍历行和单元格等,代码量较多且逻辑复杂。

对于复杂的操作,如设置单元格样式、合并单元格等,还需要编写更多的代码来实现。这使得使用 POI 进行开发时,代码的复杂度显著增加

EasyExcel

EasyExcel 对常见的 Excel 读写场景进行了高度封装,提供了极为简洁的 API。在读取 Excel 时,只需定义与表格列对应的实体类和监听器


内存占用

EasyExcel 采用基于事件驱动 的读写模式,在读写大数据量的 Excel 文件时,逐行处理数据不需要将整个文件加载到内存中 。这使得它在处理大规模数据时,内存占用非常低,能够有效避免内存溢出的问题。即使处理包含数百万行数据的 Excel 文件,也能稳定运行

POI 的用户模型 API(如 HSSFXSSF)在处理 Excel 文件时,会将整个文件加载到内存中 ,当文件数据量较大时,会占用大量的内存资源,容易导致内存溢出。虽然 POI 也提供了事件模型 API(如 SAX 解析器)来处理大数据量文件,但使用起来相对复杂,需要开发人员具备较高的技术水平


读写性能

POI :POI 的用户模型 API 在处理大数据量文件时,由于需要将整个文件加载到内存中,会导致读写效率降低。而事件模型 API 虽然在处理大数据量时性能较好,但需要手动处理事件,开发难度较大,并且在处理一些复杂操作时,效率也会受到一定影响

EasyExcel:由于采用了事件驱动的方式,EasyExcel 在读写数据时,数据处理和文件操作是同步进行的,减少了中间环节,提高了读写效率。特别是在处理大数据量文件时,其逐行处理的方式能够更快地完成读写操作

在处理大数据量的 Excel 文件时,EasyExcel 采用了基于事件驱动的读写模式,逐行处理数据,避免了将整个文件加载到内存中,从而大大降低了内存占用。例如,当需要读取一个包含数百万行数据的 Excel 文件时,使用 POI 的用户模型 API 可能会导致内存溢出,而 EasyExcel 可以稳定地处理这些数据


事件驱动为什么快+安全?

EasyExcel 通过 SAX 事件驱动 + 流式读写 ,实现了:

超低内存占用 (恒定内存,与文件大小无关)。

高效处理大文件 (GB 级 Excel 轻松应对)。

避免 OOM(彻底解决 POI 的内存瓶颈)


为什么说EasyExcel的OOM风险小

EasyExcel不需要将整个文件加载到内存中,poi需要加载整个文件?

1. 传统 POI 的 DOM 模式:全量加载

DOM(Document Object Model)

POI 将整个 Excel 文件解析为一个树形结构对象 ,全部加载到内存中。

类似于把一本书全部复印到脑子里,再逐页阅读

2. EasyExcel 的 SAX 模式:流式逐行处理

SAX(Simple API for XML)

EasyExcel 像流水线一样逐行扫描 Excel 文件,触发事件回调处理数据。

类似于用扫描仪逐页扫描一本书,读一页处理一页,然后立刻扔掉

EasyExcel 的 SAX 模式 通过事件驱动 + 即时丢弃数据(即时刷盘) ,实现了按需加载 ,而 POI 的 DOM 模式 为支持复杂功能必须全量加载


EasyExcel如何避免写入OOM?

POI必须是全量写入,这也是它的内存瓶颈

而EasyExcel 默认每处理 2000 行 (可配置)就将数据从内存刷入磁盘文件流,即时释放内存
内存占用 ≈ 单批次数据大小(而非全量数据)。例如写入sheet1然后释放sheet1,再写入sheet2,而不用sheet1,sheet2必须一起写入,分sheet页写可以实现资源及时释放


EasyExcel为啥不维护了?对此你怎么看?

核心功能已成熟,暂无重大特性新增需求。以修复 Bug 和兼容性更新为主,而非频繁发布新功能

开发者资源转移,阿里内部可能将资源投入其他更高优先级项目(如 Spring Cloud Alibaba),开源团队依赖社区贡献,但核心开发者时间有限


面试回答思路引导

面试回答

poi是apache的开源项目,功能非常丰富,而EasyExcel是基于poi的二次简化封装,简化了poi的操作,方便使用

主要让写入和写出更加简单,没必要去操作很多的细节,例如不需要手动编写输入输出流,手动关闭输入输入流的资源,编写解析器等

EasyExcel只需要只需定义与表格列对应的 实体类 监听器

EasyExcel主要解决的poi的内存瓶颈和读取效率问题

poi使用的是传统的全量加载,而EasyExcel是流失加载,也就是事件驱动+及时刷盘

poi读取的时候,必须要把整个文件加载到内存中读取

poi写入的时候必须一次性全量写入

而EasyExcel读取的时候是流式读取,逐行扫描,读取完的数据从内存中扔掉,不占用内存

EasyExcel写入的时候是流式写入,我们分sheet页写入,这个sheet页写入完就及时释放资源,实现及时刷盘不占用内存

这是他们的区别,也是基于poi的重点优化,poi因为是全量读取和写入逻辑所以oom的概率会非常大

EasyExcel是写完sheet页就释放不会一直占用内存,所以oom的概率小,但这并不说明不会出现oom问题了,使用EasyExcel的时候还是需要严格控制sheet页的,因为sheet页是存到一个List<>中的,如果sheet页过大仍然会导致oom问题


常用的方法

EasyExcel.read()

EasyExcel.write()

WriteSheet sheet = EasyExcel.writerSheet("批次").build() 构造sheet页

ExcelWriter writer = EasyExcel.write(filePath).build() 构造用来写入的ExcelWriter

writer.write(excels, sheet) 把Sheet页放到ExcelWriter里面,然后写入我们传入的内容excels列表

复制代码
    @Test
    void allData(){
        List<Excel> excels = excelMapper.selectAllOrderById();
        String filePath = "C:\\Users\\ziJian.zheng\\IdeaProjects\\Kira-Test\\src\\main\\resources\\templates\\test.xlsx";
        WriteSheet sheet = EasyExcel.writerSheet("批次" ).build();
        //用来写入的ExcelWriter
        ExcelWriter writer = EasyExcel.write(filePath).build();
        writer.write(excels, sheet);

    }

常见的注解

@ExcelProperty(value = "用户姓名",index = 0)

效果:index属性可以指定当前字段对应excel中的哪一列,可以根据列名value去匹配,也可以不写

如果不使用@ExcelProperty注解,成员变量从上到下的顺序,对应表格中 从左到右的顺序

@ExcelIgnore

读写的时候会忽略该字段

@DateTimeFormat 日期转换

日期格式转换 :将 Excel 中的日期格式数据(如 2023-01-01)与 Java 字段(StringDate)自动转换

复制代码
@DateTimeFormat("yyyy-MM-dd")  // 格式化为"2023-01-01"
private String createDate;

@NumberFormat 数字格式转换

将 Excel 中的数字(如 1,000.50)与 Java 字段(String 或数值类型)自动转换

复制代码
@NumberFormat("#,##0.00")  // 格式化为"1,000.50"
private String price;

@ExcelIgnoreUnannotated

制类字段的默认行为 :标注在类上,决定未加 @ExcelProperty 的字段是否参与读写。

不标注该注解 :所有字段(无论是否有 @ExcelProperty)都会参与读写。

标注该注解 :只有显式标注 @ExcelProperty 的字段参与读写

相关推荐
zybishe21 分钟前
免费送源码:Java+ssm+MySQL 酒店预订管理系统的设计与实现 计算机毕业设计原创定制
java·大数据·python·mysql·微信小程序·php·课程设计
anlogic2 小时前
Java基础 4.12
java·开发语言
weisian1512 小时前
Java常用工具算法-7--秘钥托管云服务2(阿里云 KMS)
java·安全·阿里云
Alt.92 小时前
SpringMVC基础二(RestFul、接收数据、视图跳转)
java·开发语言·前端·mvc
寒页_2 小时前
2025年第十六届蓝桥杯省赛真题解析 Java B组(简单经验分享)
java·数据结构·经验分享·算法·蓝桥杯
Koma-forever3 小时前
java设计模式-适配器模式
java·设计模式·适配器模式
Yolo@~3 小时前
SpringBoot无法访问静态资源文件CSS、Js问题
java·spring boot·后端
Jennifer33K3 小时前
IDEA 调用 Generate 生成 Getter/Setter 快捷键
java·ide·intellij-idea
爱的叹息3 小时前
JDK(Java Development Kit)从发布至今所有主要版本 的详细差异、新增特性及关键更新的总结,按时间顺序排列
java·数据库·python
Dong雨3 小时前
Maven error:Could not transfer artifact
java·maven