EasyExcel 读取不到数据

在使用EasyExcel进行Excel数据导入时遇到监听器无响应的难题,经过一系列排查,发现IDEA默认生成的ReadListener接口实现中,hasNext方法返回了false,导致解析停止。因此,解决办法是避免实现这个方法或者确保hasNext返回正确值,以使监听器正常工作。

接到个需求要做Excel的数据导入,很自然的想到了用EasyExcel 来做,参照官方写法,很快就写完·代码了。搞定前端文件上传后,开始前后端联调测试。奇怪的问题发生了。。监听器一点反应都没有,咋回事???一通百度,看官网issue 都没解决。没办法了,自己开始各种尝试。

最终发现是因为是实现的 ReadListener 接口的时候,IDEA默认会把接口中的方法全部覆写如下图:

 

关键来了!!! hasNext 自动给return false !!! 这将导致不进行下一步的解析。所以监听器才会一点反应都没有。。。。 实现ReadListener的时候特别注意下 hasNext 方法就别实现了。

<think>好的,我现在需要帮助用户解决如何使用EasyExcel读取Excel文件中的原始数据。首先,我得回忆一下EasyExcel的基本使用方法,以及用户提到的引用内容。 根据引用[4],EasyExcel采用SAX解析,低内存占用,适合大文件处理。用户需要获取原始数据,可能包括单元格值、格式或公式。但EasyExcel默认是处理数据的,可能不会直接保留所有原始信息,比如公式可能需要特别处理。 用户的问题是如何用EasyExcel获取原始数据。首先,我需要确定“原始数据”指的是什么。如果是单元格的值,包括字符串、数字等,那么常规的读取方式就可以。但如果需要公式计算前的值或者单元格的样式,可能需要更深入的配置。 引用[4]还提到监听器模式,用于分页读取数据量。所以,使用读取监听器是关键。常规做法是继承AnalysisEventListener,重写invoke方法处理每一行数据。但是要获取原始数据,可能需要访问单元格本身的信息,而不仅仅是解析后的对象。 查看EasyExcel的文档(引用[2]和[3]),读取时可以指定自定义的ReadListener,并通过AnalysisContext获取当前行的原始数据。例如,在invoke方法中,可以通过context.readRowHolder().getCellMap()来获取单元格的原始值,这可能包括字符串形式的数字或公式结果。 另外,用户可能需要处理不同的数据类型,比如日期或数字格式。EasyExcel默认会进行类型转换,但若需要原始字符串,可能需要禁用转换器,或者在读取时保留字符串形式。例如,在读取时添加@ExcelProperty注解,使用converter指定字符串转换器。 还需要考虑Excel的版本,.xls和.xlsx的处理是否一致。根据引用[4],EasyExcel支持这两种格式,所以应该没问题。 可能用户会遇到合并单元格的情况,这时候需要判断单元格是否为合并区域,但EasyExcel的监听器可能无法直接处理,需要额外的逻辑或者在读取后处理数据。 总结步骤应该是:创建实体类(可选)、创建监听器、构建读取器并执行读取。如果不需要映射到对象,可以直接读取为Map或使用无模型模式,这样每一行数据以Map形式呈现,键为列索引或标题。 另外,引用[5]提到接口封装和灵活性,可能建议用户将读取逻辑封装成可复用的组件,方便后续扩展。 最后,需要验证示例代码的正确性,确保使用正确的方法和类,比如ExcelReaderBuilder、sheet方法、headRowNumber设置等。同时,提醒用户注意异常处理和资源释放,比如在finally块中关闭流。</think>以下是使用EasyExcel获取Excel原始数据的完整解决方案: ### 一、基础读取方式 通过监听器模式逐行读取原始数据,核心方法如下: ```java public class RawDataListener extends AnalysisEventListener<Map<Integer, String>> { private List<Map<Integer, String>> rawData = new ArrayList<>(); @Override public void invoke(Map<Integer, String> rowData, AnalysisContext context) { // 获取单元格原始字符串值 Map<Integer, CellData> cellMap = context.readRowHolder().getCellMap(); Map<Integer, String> row = new HashMap<>(); cellMap.forEach((colIndex, cell) -> { row.put(colIndex, cell.getStringValue()); // 原始字符串值 }); rawData.add(row); } public List<Map<Integer, String>> getRawData() { return rawData; } } ``` ### 二、关键配置步骤 1. **设置不自动转换类型**: ```java ReadSheet readSheet = EasyExcel.readSheet(0) .headRowNumber(0) // 从第0行开始读取 .build(); EasyExcel.read(inputStream, new RawDataListener()) .autoTrim(false) // 保留原始空格 .autoCloseStream(true) .read(readSheet); ``` 2. **获取元数据**: ```java // 获取总行数(含空行) context.readSheetHolder().getTotal(); // 获取单元格样式 cell.getCellStyle().getDataFormatString(); ``` ### 三、完整示例代码 ```java public List<Map<Integer, String>> readRawData(String filePath) { try (InputStream in = new FileInputStream(filePath)) { RawDataListener listener = new RawDataListener(); ExcelReader excelReader = EasyExcel.read(in, listener) .autoTrim(false) .ignoreEmptyRow(false) // 包含空行 .build(); ReadSheet readSheet = EasyExcel.readSheet(0) .headRowNumber(0) .build(); excelReader.read(readSheet); return listener.getRawData(); } } ``` ### 四、注意事项 1. 公式单元格需特殊处理: ```java if (cell.getType() == CellType.FORMULA) { String formula = cell.getFormulaValue(); // 获取公式 String cachedValue = cell.getStringValue(); // 获取缓存值 } ``` 2. 日期数据会返回Excel内部数值格式,需自行转换[^4] 3. 合并单元格会重复出现在多个行记录中
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值