跳转至

POI 解析 Excel 注意事项

一、POI 两种模式

模式 内存 适用
用户模式 XSSFWorkbook 全量加载,内存大 小文件
SAX 模式 XSSFReader 边读边处理 大文件

大文件用用户模式直接 OOM。

二、常见坑

1. 大文件 OOM

10 万行 Excel,new XSSFWorkbook(inputStream) 把整个文件解析成对象树,内存翻几倍。

解决: - 用 SXSSF(写大文件)。 - 用 SAX / EasyExcel(读大文件)。

2. 数字 cell 变科学计数法

cell.getNumericCellValue();  // 1.23456E7

要格式化:

DataFormatter formatter = new DataFormatter();
String text = formatter.formatCellValue(cell);

3. 日期格式

getNumericCellValue() 拿日期是一个 double,要用:

Date date = DateUtil.getJavaDate(cell.getNumericCellValue());

4. 空行 / 空 cell

POI 默认不返回空 cell,遍历时要判断。

5. 3.5 万行问题

xlsx 是 zip + XML,POI 解析时会建很多对象。生产环境推荐 EasyExcel(阿里开源),SAX 模式,内存稳定。

三、EasyExcel 示例

EasyExcel.read(fileName, UserDTO.class, new ReadListener<UserDTO>() {
    @Override
    public void invoke(UserDTO data, AnalysisContext context) {
        // 逐行处理
    }
    @Override
    public void doAfterAllAnalysed(AnalysisContext context) { }
}).sheet().doRead();

四、写 Excel

  • 小文件:XSSFWorkbook
  • 大文件:SXSSFWorkbook(滑动窗口,内存只保留 N 行)。
SXSSFWorkbook wb = new SXSSFWorkbook(100); // 窗口 100 行

用完要 wb.dispose() 删除临时文件。

五、注意

  • 及时关闭流。
  • 不要把 Excel 全量读进内存再处理,流式读、批量写 DB。
  • 用 EasyExcel 替代原生 POI。

面试加分

  • POI 大文件 OOM 是经典问题,答出 SAX / EasyExcel。
  • SXSSF 写大文件靠磁盘临时文件。