EasyExcel 与 Apache POI 版本冲突导致的 `NoSuchMethodError` 异常
EasyExcel 与 Apache POI 版本冲突导致的 `NoSuchMethodError` 异常
- 一、背景:EasyExcel 与 Apache POI 的关系
- 二、典型错误场景
- 场景一:项目中已引入了 POI,再引入 EasyExcel
- 场景二:EasyExcel 与 POI 版本不兼容
- 三、解决方案
- 方案一:排除 EasyExcel 自带的 POI,手动指定统一版本(推荐)
- 方案二:如果项目不直接使用 POI,直接移除自己引入的 POI
- 四、总结

最近在使用 EasyExcel 导出 Excel 时,遇到了类似这样的异常:

Caused by: java.lang.NoSuchMethodError: org.apache.poi.util.StringUtil.isNotBlank(Ljava/lang/CharSequence;)Zat org.apache.poi.openxml4j.opc.OPCPackage.close(OPCPackage.java:462)at org.apache.poi.ooxml.POIXMLDocument.close(POIXMLDocument.java:189)at org.apache.poi.xssf.usermodel.XSSFWorkbook.close(XSSFWorkbook.java:610)at org.apache.poi.xssf.streaming.SXSSFWorkbook.close(SXSSFWorkbook.java:972)at com.alibaba.excel.context.WriteContextImpl.finish(WriteContextImpl.java:383)
这个错误在 Stack Overflow 和国内社区里都出现过很多次。
看起来像是 POI 的 bug,但其实 根本原因是 “依赖冲突 + 版本不兼容”。
一、背景:EasyExcel 与 Apache POI 的关系
阿里巴巴的 EasyExcel 是一个基于 Apache POI 封装的轻量级 Excel 操作框架。
也就是说:
-
EasyExcel 本身不直接操作 XLSX 文件;
-
它在底层依然依赖 Apache POI(poi、poi-ooxml、poi-ooxml-schemas) 来读写文件。
因此,当你的项目中出现多个 POI 版本时,很容易导致类加载冲突。
二、典型错误场景
场景一:项目中已引入了 POI,再引入 EasyExcel
举个例子:
<!-- 你自己引入的 POI -->
<dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>3.17</version>
</dependency><!-- 后来又加了 EasyExcel -->
<dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>4.0.3</version>
</dependency>
这时候,项目中会同时存在两套 POI 版本:
| 依赖来源 | 版本 | 特点 |
|---|---|---|
| 你自己的 POI | 3.17 | 老版本,没有 StringUtil.isNotBlank 方法 |
| EasyExcel 内部 POI | 4.x | 新版本,增加了 isNotBlank 方法 |
当 JVM 加载类时,如果先加载了旧版本的 poi,
EasyExcel 内部再去调用新版本方法(例如 StringUtil.isNotBlank(CharSequence)),
就会抛出:
NoSuchMethodError: org.apache.poi.util.StringUtil.isNotBlank(Ljava/lang/CharSequence;)Z
本质原因:运行时类加载顺序导致的 方法签名缺失。
场景二:EasyExcel 与 POI 版本不兼容
即使你只引入了 EasyExcel,一些 IDE 或父依赖(如 Spring Boot Starter)可能传递进了 不兼容版本的 POI。
例如:
-
EasyExcel 4.0.3 编译依赖 POI 4.1.2;
-
但 Spring Boot 传递进了 POI 5.2.x;
-
运行时会出现某些类或方法签名不匹配(比如
StringUtil.isNotBlank、POIXMLDocument.close)。
本质原因:EasyExcel 依赖的 POI 方法签名在高版本中被修改或删除。
三、解决方案
方案一:排除 EasyExcel 自带的 POI,手动指定统一版本(推荐)
<!-- EasyExcel 导出(排除内部 POI 依赖) -->
<dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>4.0.3</version><exclusions><exclusion><groupId>javax.servlet</groupId><artifactId>servlet-api</artifactId></exclusion><exclusion><groupId>org.apache.poi</groupId><artifactId>poi</artifactId></exclusion><exclusion><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId></exclusion><exclusion><groupId>org.apache.poi</groupId><artifactId>poi-ooxml-schemas</artifactId></exclusion></exclusions>
</dependency><!-- 手动指定兼容版本 POI(与 EasyExcel 4.0.3 完美匹配) -->
<dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>4.1.2</version>
</dependency>
说明:EasyExcel 4.0.3 的源码中基于 POI 4.1.x 版本构建,因此与之兼容性最佳。
方案二:如果项目不直接使用 POI,直接移除自己引入的 POI
如果你的项目只通过 EasyExcel 操作 Excel,没有直接使用 POI 的 API,
那么最简单的方式是删除多余的 POI 依赖:
<!-- 保留 EasyExcel 即可 -->
<dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>4.0.3</version>
</dependency>
四、总结
| 问题类型 | 根本原因 | 解决方式 |
|---|---|---|
| 依赖冲突 | 项目中同时存在多个 POI 版本 | 排除 EasyExcel 内部 POI,只保留一个版本 |
| 版本不兼容 | EasyExcel 与当前 POI 方法签名不同 | 使用与 EasyExcel 匹配的 POI 版本(如 4.1.2) |
最简单的经验法则:
-
只用 EasyExcel → 不要单独引入 POI。
-
同时用 POI + EasyExcel → 统一 POI 版本并排除 EasyExcel 自带的依赖。
结语:
NoSuchMethodError并不是 EasyExcel 的 bug,而是依赖管理的问题。
只要理清依赖树、保持 POI 版本一致,就能彻底解决此类冲突。
