前言:使用 EasyExcel 导出的核心原理基于 流式写入 和 事件驱动模型,通过分批次处理数据、动态生成 Excel 文件,避免一次性加载全量数据到内存,从而显著降低内存占用。以下是其详细流程和原理分析:
一、核心原理
流式写入(Streaming Write)
通过 Apache POI 的 SXSSFWorkbook 实现,将数据分批次写入磁盘,而非一次性加载到内存。
默认每 100 行数据生成一个临时文件块,避免内存溢出(OOM)。
事件驱动模型:
通过注解驱动(如 @ExcelProperty)自动解析数据模型,生成表头和内容。
使用模板引擎动态填充数据,支持复杂格式和样式。
内存优化:
对象复用:复用 Cell 和 Row 对象,减少 JVM 垃圾回收压力。
分片处理:按需加载数据,适合大数据量场景(如百万级数据导出)。
二、导出流程详解
以下是 EasyExcel 导出 Excel 的完整流程:
-
初始化写入器
ExcelWriter excelWriter = EasyExcel.write(fileName, DemoData.class).build();
创建 ExcelWriter 对象,绑定数据模型类(DemoData.class)。
解析类上的 @ExcelProperty 注解,生成表头元数据。
-
创建 Sheet 页
WriteSheet writeSheet = EasyExcel.writerSheet("Sheet1").build();
定义 Sheet 名称和样式(如列宽、表头颜色等)。
-
分批次写入数据
excelWriter.write(dataList, writeSheet);
数据分块:将数据按批次(如每 100 行)写入临时文件。
事件触发:每写入一行数据,触发 CellWriteHandler 事件,处理样式、超链接等。
-
资源释放
excelWriter.finish();
关闭临时文件流,合并所有分块文件,生成最终 Excel 文件。
清理临时文件和内存缓存。
三、关键组件解析
-
数据模型解析
注解驱动:通过 @ExcelProperty 定义字段与 Excel 列的映射关系。@ExcelProperty("姓名")
private String name;
类型转换:内置 Converter 处理日期、数字等格式(如 @DateTimeFormat("yyyy-MM-dd"))。 -
写入处理器(WriteHandler)
样式处理器:自定义表头、单元格样式。.registerWriteHandler(new CustomCellStyleStrategy())
行处理器:在写入每行前后插入逻辑(如设置行高)。
- 临时文件管理
默认使用 SXSSFWorkbook,将超出内存阈值的数据写入磁盘临时文件。
临时文件路径可通过 setTempFile 自定义。
四、性能优化机制
- 内存控制
机制 描述
分片写入 每批次处理固定行数(默认 100 行)
对象池 复用 Row 和 Cell 对象,减少 GC
磁盘缓存 大数据量时自动切换为文件存储 - 异步刷新
通过 AsyncSheet 实现异步写入,提升吞吐量。
示例:
EasyExcel.write(fileName, DemoData.class)
.asyncSheet()
.doWrite(dataList);
-
动态列处理
动态生成表头,无需预定义数据模型:List<List<String>> head = Arrays.asList(
Arrays.asList("姓名"),
Arrays.asList("年龄")
);
EasyExcel.write(fileName).head(head).sheet().doWrite(data);
五、异常处理与调试
常见异常
ExcelGenerateException:写入逻辑错误(如文件路径不可写)。
ConverterException:数据格式转换失败(如日期格式不匹配)。
调试建议
开启调试日志:
Logger logger = LoggerFactory.getLogger(EasyExcel.class);
logger.debug("开启 EasyExcel 调试日志");
捕获并处理异常:
try {
EasyExcel.write(...).doWrite(...);
} catch (Exception e) {
System.err.println("导出失败: " + e.getMessage());
} finally {
excelWriter.finish();
}
六、流程总结
准备数据 → 2. 初始化写入器 → 3. 解析注解 → 4. 分批次写入 → 5. 合并临时文件 → 6. 生成最终 Excel。
通过以上设计,EasyExcel 在保证高性能的同时,显著降低了内存占用,尤其适合大数据量导出场景。开发者只需关注数据模型和业务逻辑,无需深入处理底层 Excel 格式的复杂性。