本文详细介绍阿里巴巴开源的EasyExcel库,涵盖Maven依赖引入、读写API核心用法及注解配置。重点解析多线程并发读取、多Sheet写入、分页批量导出等生产环境实用技巧,并提供Spring Boot中文件上传下载的完整代码示例,解决大数据量导出时的内存溢出与性能瓶颈问题。
EasyExcel 核心优势与引入
在处理后端 Excel 数据导出需求时,传统的 apache-poi 库常因全量加载数据到内存而导致 OutOfMemoryError。EasyExcel 作为阿里开源的解决方案,通过流式读写和按需解析机制,有效避免了内存泄漏问题,特别适合处理百万级数据量的场景。

在 Maven 项目中引入 EasyExcel 依赖,当前稳定版本建议参考官方最新文档(如 3.x 系列),以获取更好的性能优化和新特性支持:
com.alibaba
easyexcel
3.1.1
EasyExcel 读写 API 详解
EasyExcel 的设计围绕“读”和“写”两个核心操作展开,采用 Builder 模式构建实例,并通过监听器(Listener)处理数据回调。
第1步:实现 Excel 数据读取
读取 Excel 文件时,推荐使用 AnalysisEventListener 监听器来逐行处理数据,避免一次性加载所有数据到内存。根据业务需求,可以选择将数据解析为 Map 或自定义对象。
场景 A:解析为 Map(高性能推荐)
当数据量巨大且无需复杂对象转换时,直接解析为 Map 可避免反射开销,显著提升读取速度。
EasyExcel.read("file.xlsx")
.sheet()
.registerReadListener(new AnalysisEventListener场景 B:解析为自定义对象(类型安全)
通过 @ExcelProperty 注解映射列头与字段,适合业务逻辑复杂的场景。
@Data
public class OrderData {
@ExcelProperty("订单编号")
private String orderId;
@ExcelProperty("手机号")
private String phone;
}
EasyExcel.read("file.xlsx", OrderData.class, new AnalysisEventListener() {
@Override
public void invoke(OrderData data, AnalysisContext context) {
// 处理解析后的对象
}
}).doRead(); 第2步:实现 Excel 数据写入
写入操作同样采用 Builder 模式,通过 ExcelWriter 实例将数据写入文件。务必调用 finish() 方法确保文件完整写入。
List data = ...; // 准备数据
EasyExcel.write("output.xlsx", OrderData.class)
.sheet("订单列表")
.doWrite(data); 生产环境实用技巧
在实际项目中,常遇到大数据量导出、多 Sheet 处理及高并发读取等挑战。以下是经过验证的解决方案。
第3步:多线程并发读取优化
当需要处理多个格式一致的 Excel 文件时,可使用多线程并发读取以缩短总耗时。注意:源文件必须已分割且列结构一致,且需确保服务器内存充足以合并结果。
ThreadPoolExecutor executor = new ThreadPoolExecutor(
Runtime.getRuntime().availableProcessors(),
Runtime.getRuntime().availableProcessors() * 2,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue()
);
List>>> futures = files.stream()
.map(file -> executor.submit(() -> {
List 注意:Excel 写入操作不支持并发,否则会导致文件损坏或数据错乱。
第4步:多 Sheet 写入与分页批量导出
多 Sheet 写入:使用同一个 ExcelWriter 实例,通过创建多个 WriteSheet 对象写入不同 Sheet。
ExcelWriter writer = EasyExcel.write("multi.xlsx").build();
WriteSheet sheet1 = EasyExcel.writerSheet("Sheet1").head(OrderData.class).build();
WriteSheet sheet2 = EasyExcel.writerSheet("Sheet2").head(UserData.class).build();
writer.write(data1, sheet1);
writer.write(data2, sheet2);
writer.finish();分页批量导出(百万级数据):为避免内存溢出,采用“分页查询 -> 转换 -> 写入”的模板模式,逐批写入数据。
ExcelWriter writer = EasyExcel.write(outputStream, OrderData.class).build();
WriteSheet sheet = EasyExcel.writerSheet("订单").build();
int pageNum = 1;
while (true) {
List pageData = orderService.selectPage(pageNum++, 1000);
if (pageData.isEmpty()) break;
writer.write(pageData, sheet);
}
writer.finish(); Spring Boot 中的文件上传与下载
在 Web 应用中,EasyExcel 可与 Spring MVC 无缝集成,实现文件的上传解析与下载导出。
第5步:实现文件上传解析
通过 MultipartHttpServletRequest 获取文件流,直接传入 EasyExcel.read()。
@PostMapping("/upload")
public ResponseEntity upload(MultipartHttpServletRequest request) {
Map fileMap = request.getFileMap();
for (MultipartFile file : fileMap.values()) {
EasyExcel.read(file.getInputStream(), OrderData.class, new AnalysisEventListener() {
@Override
public void invoke(OrderData data, AnalysisContext context) {
// 处理业务逻辑
}
}).doRead();
}
return ResponseEntity.ok("Success");
} 第6步:实现文件下载导出
下载时需设置正确的 Content-Type 和 Content-Disposition 头,并对中文文件名进行 URL 编码以防乱码。
@GetMapping("/download")
public void download(HttpServletResponse response) throws IOException {
String fileName = URLEncoder.encode("订单数据.xlsx", StandardCharsets.UTF_8.toString());
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
List data = orderService.selectAll();
EasyExcel.write(response.getOutputStream(), OrderData.class)
.sheet("订单")
.doWrite(data);
} 配置提醒:
1. 大文件上传需调整 spring.servlet.multipart.max-request-size。
2. 若使用 Nginx,需增加 proxy_read_timeout 和 client_body_timeout 配置。
常见问题与排查
- 问题:导出文件损坏或打不开。
原因:未调用writer.finish()或流未正确关闭。
解决:确保在try-finally块中调用finish(),或使用autoCloseStream(true)。 - 问题:中文文件名乱码。
原因:未进行 URL 编码或浏览器兼容性问题。
解决:使用URLEncoder.encode(fileName, "UTF-8"),并针对 Safari 浏览器做特殊处理(RFC 5987 标准)。 - 问题:内存溢出(OOM)。
原因:一次性加载大量数据或使用apache-poi的HSSFWorkbook。
解决:使用 EasyExcel 的流式读写,或采用分页批量写入策略。
总结
EasyExcel 通过其简洁的 API 设计和高效的内存管理机制,成为 Java 生态中处理 Excel 文件的首选工具。掌握其读写 API、多线程读取、多 Sheet 写入及分页导出技巧,能够有效应对从简单报表到百万级数据导出的各种复杂场景。在实际开发中,注意文件流关闭、中文编码及大文件配置优化,可确保系统的稳定与高效。
以上就是 EasyExcel 实战指南的详细内容,更多关于 Java Excel 操作优化的资料请关注本站其它相关文章!







