读取.xlsx文件时遭遇java.lang.NoSuchFieldError错误求助
解决java.lang.NoSuchFieldError: SMALLER_BIG_BLOCK_SIZE_DETAILS错误
这个错误我碰到过好几次,本质就是Apache POI依赖的版本不兼容或者冲突导致的——你的代码想访问POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS这个字段,但JVM加载的POIFSConstants类里根本没有它,咱们一步步排查解决:
错误根源分析
- 版本不匹配:
SMALLER_BIG_BLOCK_SIZE_DETAILS这个字段是在Apache POI 3.17版本之后引入的,如果你用的是更早的POI版本,自然找不到这个字段;反过来,如果你的代码是基于旧版本编写,但引入了过新的POI,也可能遇到字段被移除/重命名的问题。 - 依赖冲突:项目里如果同时存在多个不同版本的POI相关依赖(比如
poi、poi-ooxml、poi-scratchpad这些),类加载器可能会加载错误版本的POIFSConstants类,导致找不到目标字段。
具体解决方案
1. 统一所有POI相关依赖的版本
确保项目里所有POI家族的依赖都使用同一个稳定版本,比如目前推荐用5.2.5(稳定且兼容性好)。
如果用Maven,修改pom.xml:
<dependencies> <!-- 核心POI依赖 --> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>5.2.5</version> </dependency> <!-- 处理xlsx格式的依赖 --> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>5.2.5</version> </dependency> </dependencies>
如果用Gradle,修改build.gradle:
dependencies { implementation 'org.apache.poi:poi:5.2.5' implementation 'org.apache.poi:poi-ooxml:5.2.5' }
2. 排查并移除冲突的依赖
很多时候是第三方依赖偷偷引入了旧版本的POI,这时候需要用依赖分析工具揪出来:
- Maven执行命令:
mvn dependency:tree - Gradle执行命令:
gradle dependencies
输出结果里找所有org.apache.poi开头的依赖,要是发现有版本不一致的,就在对应的第三方依赖里排除掉旧版本的POI。比如:
<dependency> <groupId>第三方依赖groupId</groupId> <artifactId>第三方依赖artifactId</artifactId> <version>1.0.0</version> <exclusions> <exclusion> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> </exclusion> <exclusion> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> </exclusion> </exclusions> </dependency>
3. 优化代码兼容性
你的代码里用了强制转换(XSSFWorkbook) WorkbookFactory.create(...),其实可以改成多态写法,避免版本变更带来的类型转换问题:
Workbook workbook = WorkbookFactory.create(new File("C:\\sanjay\\InspectionFormTpl.xlsx")); // 如果确定是xlsx格式,再转成XSSFWorkbook if (workbook instanceof XSSFWorkbook) { XSSFWorkbook xSSFWorkbook = (XSSFWorkbook) workbook; // 后续逻辑... }
另外,确认你使用的POI版本中POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS确实存在——比如POI 5.x系列这个字段是保留的,放心用。
4. 清理缓存重新构建
最后别忘了清理项目的编译缓存:
- Maven:执行
mvn clean install - Gradle:执行
gradle clean build
这样能确保项目用的都是你指定的最新依赖,不会残留旧的编译产物。
按照上面的步骤来,应该就能解决这个字段找不到的问题,顺利读取你的xlsx文件了。
内容的提问来源于stack exchange,提问作者sanjay sharma




