使用Apache POI读取Excel时出现java.lang.NoSuchMethodError错误求助
排查Apache POI读取Excel时的
java.lang.NoSuchMethodError错误 我来帮你搞定这个问题——java.lang.NoSuchMethodError在Apache POI使用场景里简直是常客,绝大多数情况都和依赖版本或者类路径冲突有关。先结合你的代码(虽然没写完,但核心逻辑是初始化XSSFWorkbook),咱们一步步拆解原因和解决办法:
常见错误原因
- 依赖版本不匹配:这是最核心的问题。Apache POI的各个组件(比如
poi、poi-ooxml、poi-ooxml-schemas等)必须保持完全一致的版本号。要是你混用了不同版本的组件(比如用了poi 4.1.2但poi-ooxml是5.0.0),就会出现方法找不到的情况——因为新版本的类可能移除或修改了旧版本的方法,反之亦然。 - 缺失必要依赖:
XSSFWorkbook属于处理.xlsx格式的组件,必须依赖poi-ooxml包。如果只引入了基础的poi核心包,没加poi-ooxml,或者缺少它的附属依赖(比如xmlbeans、curvesapi),也会触发这个错误。 - 类路径冲突:项目里可能存在其他和POI冲突的库,比如旧版本的POI jar包、其他Excel处理库(比如jxl),导致JVM加载了错误版本的类,自然找不到目标方法。
解决办法
1. 统一所有POI相关依赖的版本
不管你是用Maven/Gradle管理依赖,还是手动导入jar包,一定要确保所有POI相关组件版本完全一致。
Maven示例配置:
<dependencies> <!-- 处理.xls格式的核心包 --> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>5.2.5</version> <!-- 所有POI依赖用同一个版本 --> </dependency> <!-- 处理.xlsx格式的必要包 --> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>5.2.5</version> </dependency> </dependencies>
手动导入jar包注意事项:
要确保以下jar包版本一致:
poi.jarpoi-ooxml.jarpoi-ooxml-full.jar(5.x版本后推荐用这个替代poi-ooxml-schemas.jar)xmlbeans.jarcurvesapi.jar
2. 排查并移除冲突依赖
- 如果用Maven,执行
mvn dependency:tree命令查看依赖树,找出重复或版本不一致的POI相关依赖,用<exclusions>标签排除掉旧版本的。 - 如果是手动管理jar包,检查项目的
lib目录,删掉所有重复、版本不一致的POI相关jar文件,只保留一套同版本的。
3. 补全必要的依赖
处理.xlsx文件必须引入poi-ooxml依赖,它包含了XSSFWorkbook所需的所有类和附属依赖。5.x版本的poi-ooxml已经内置了大部分必要依赖,不需要额外手动引入,除非有特殊场景。
补全后的示例代码
你的代码没写完,这里给你补全一个正确的读取示例,顺便用try-with-resources自动关闭流,避免资源泄漏:
import java.util.*; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.InputStream; import java.io.IOException; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.apache.poi.xssf.usermodel.XSSFSheet; public class ExcelRead{ public static void main(String[] args){ String docName = "C:\\Users\\Name\\Desktop\\excelExample.xlsx"; // 使用try-with-resources自动关闭输入流和工作簿 try(InputStream xlsxDoc = new FileInputStream(docName); XSSFWorkbook wb = new XSSFWorkbook(xlsxDoc)){ XSSFSheet sheet = wb.getSheetAt(0); // 获取第一个工作表 // 遍历行和单元格 for(Row row : sheet){ for(Cell cell : row){ // 根据单元格类型处理数据 switch(cell.getCellType()){ case STRING: System.out.print(cell.getStringCellValue() + "\t"); break; case NUMERIC: System.out.print(cell.getNumericCellValue() + "\t"); break; case BOOLEAN: System.out.print(cell.getBooleanCellValue() + "\t"); break; default: System.out.print("Unknown type\t"); } } System.out.println(); } } catch (FileNotFoundException e) { e.printStackTrace(); System.err.println("找不到目标Excel文件,请检查路径是否正确"); } catch (IOException e) { e.printStackTrace(); System.err.println("读取Excel文件时发生IO错误"); } } }
内容的提问来源于stack exchange,提问作者Fancypants753




