前言
在Java开发中,处理Excel文件是一个常见的需求。无论是数据导入导出、报表生成,还是批量数据处理,Excel操作都是不可避免的。传统的POI库虽然功能强大,但使用起来相对复杂,而且在处理大量数据时容易出现内存溢出问题。今天要介绍的EasyExcel,正是为了解决这些痛点而生的优秀框架。
什么是EasyExcel?
EasyExcel是阿里巴巴开源的一个基于Java的Excel处理工具,它重写了POI对Excel的解析,能够原本一个3M的Excel用POI sax解析依然需要100M左右内存,改用EasyExcel可以降低到几M,并且再大的Excel也不会出现内存溢出的情况。
主要特性
-
内存占用低:避免OOM(内存溢出)
-
使用简单:基于注解的模式,代码简洁
-
功能丰富:支持读写、样式设置、数据验证等
-
性能优越:处理速度快,支持大文件操作
快速上手
添加依赖
首先在项目中添加EasyExcel依赖:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.3.2</version>
</dependency>
创建数据模型
使用注解定义Excel表格结构:
public class User {
@ExcelProperty("用户ID")
private Long id;
@ExcelProperty("用户名")
private String username;
@ExcelProperty("邮箱")
private String email;
@ExcelProperty(value = "注册时间", converter = LocalDateTimeConverter.class)
private LocalDateTime createTime;
// 构造方法、getter、setter省略
}
核心功能示例
1. 读取Excel文件
public class ExcelReader {
public void readExcel() {
String fileName = "user_data.xlsx";
// 简单读取
EasyExcel.read(fileName, User.class, new UserDataListener())
.sheet()
.doRead();
}
}
// 数据监听器
public class UserDataListener extends AnalysisEventListener<User> {
@Override
public void invoke(User user, AnalysisContext context) {
// 处理每一行数据
System.out.println("读取到用户:" + user.getUsername());
// 可以进行数据验证、入库等操作
}
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
System.out.println("所有数据解析完成!");
}
}
2. 写入Excel文件
public class ExcelWriter {
public void writeExcel() {
String fileName = "output_users.xlsx";
// 准备数据
List<User> users = getUserList();
// 写入Excel
EasyExcel.write(fileName, User.class)
.sheet("用户信息")
.doWrite(users);
}
private List<User> getUserList() {
List<User> users = new ArrayList<>();
users.add(new User(1L, "张三", "zhangsan@example.com", LocalDateTime.now()));
users.add(new User(2L, "李四", "lisi@example.com", LocalDateTime.now()));
return users;
}
}
3. 自定义样式
// 自定义样式写入
EasyExcel.write(fileName, User.class)
.registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()) // 自适应列宽
.registerWriteHandler(getHorizontalCellStyleStrategy()) // 自定义样式
.sheet("用户信息")
.doWrite(users);
private HorizontalCellStyleStrategy getHorizontalCellStyleStrategy() {
// 头部样式
WriteCellStyle headWriteCellStyle = new WriteCellStyle();
headWriteCellStyle.setFillForegroundColor(IndexedColors.BLUE.getIndex());
WriteFont headWriteFont = new WriteFont();
headWriteFont.setFontHeightInPoints((short) 12);
headWriteFont.setBold(true);
headWriteCellStyle.setWriteFont(headWriteFont);
// 内容样式
WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
contentWriteCellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());
return new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);
}
高级特性
数据验证
public class User {
@ExcelProperty("用户名")
@NotBlank(message = "用户名不能为空")
private String username;
@ExcelProperty("邮箱")
@Email(message = "邮箱格式不正确")
private String email;
@ExcelProperty("年龄")
@Min(value = 0, message = "年龄不能小于0")
@Max(value = 150, message = "年龄不能大于150")
private Integer age;
}
动态表头
// 动态生成表头
List<List<String>> head = new ArrayList<>();
head.add(Arrays.asList("用户信息", "基本信息", "ID"));
head.add(Arrays.asList("用户信息", "基本信息", "姓名"));
head.add(Arrays.asList("用户信息", "联系方式", "邮箱"));
EasyExcel.write(fileName)
.head(head)
.sheet("动态表头")
.doWrite(data);
最佳实践
1. 处理大文件
// 使用分批处理避免内存问题
public class BatchUserDataListener extends AnalysisEventListener<User> {
private static final int BATCH_COUNT = 1000;
private List<User> cachedDataList = new ArrayList<>();
@Override
public void invoke(User user, AnalysisContext context) {
cachedDataList.add(user);
if (cachedDataList.size() >= BATCH_COUNT) {
saveData();
cachedDataList.clear();
}
}
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
saveData();
}
private void saveData() {
// 批量保存数据
userService.saveBatch(cachedDataList);
}
}
2. 异常处理
try {
EasyExcel.read(fileName, User.class, new UserDataListener())
.sheet()
.doRead();
} catch (Exception e) {
log.error("Excel读取失败:{}", e.getMessage(), e);
throw new BusinessException("文件解析失败,请检查文件格式");
}
总结
EasyExcel作为一个优秀的Excel处理框架,具有以下优势:
-
简单易用:基于注解的配置方式,降低学习成本
-
性能优异:内存占用低,处理速度快
-
功能全面:支持读写、样式、验证等多种特性
-
扩展性强:提供丰富的自定义接口
无论是简单的数据导入导出,还是复杂的报表生成,EasyExcel都能提供优雅的解决方案。在实际项目中,建议结合业务需求选择合适的使用方式,并注意异常处理和性能优化。
通过本文的介绍,相信你已经对EasyExcel有了基本的了解。更多高级用法和特性,建议查阅官方文档进行深入学习。让我们一起用EasyExcel让Excel操作变得更加简单高效!