本文目录导读:

下面我为你详细介绍 EasyExcel 的使用方法,这是阿里开源的一个非常好用的 Java Excel 工具库,特别适合处理大数据量、内存占用低的场景。
EasyExcel 简介
核心优势:
- 内存占用极低(相比 POI,能节省 90% 以上)
- 使用简单,API 友好
- 支持大数据量的读写(百万级)
- 支持模板填充
Maven 依赖:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.3.2</version>
</dependency>
注意:如果你的项目中使用 Lombok,建议搭配使用,可以少写很多 Getter/Setter 代码。
快速入门:写 Excel
最简单的写操作
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;
// 1. 先定义数据模型
@Data
public class UserData {
@ExcelProperty("用户ID")
private Long userId;
@ExcelProperty("用户名")
private String userName;
@ExcelProperty("年龄")
private Integer age;
@ExcelProperty("邮箱")
private String email;
}
// 2. 写入数据
public class WriteTest {
public static void main(String[] args) {
// 准备数据
List<UserData> userList = new ArrayList<>();
for (int i = 0; i < 10; i++) {
UserData user = new UserData();
user.setUserId((long) i);
user.setUserName("用户" + i);
user.setAge(20 + i);
user.setEmail("user" + i + "@example.com");
userList.add(user);
}
// 写入 Excel
String fileName = "用户数据.xlsx";
EasyExcel.write(fileName, UserData.class)
.sheet("用户信息")
.doWrite(userList);
System.out.println("写入成功!");
}
}
自定义样式和格式
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
public class WriteWithStyle {
public static void main(String[] args) {
// 设置表头样式
WriteCellStyle headStyle = new WriteCellStyle();
WriteFont headFont = new WriteFont();
headFont.setBold(true);
headFont.setFontHeightInPoints((short) 12);
headFont.setColor(IndexedColors.WHITE.getIndex());
headStyle.setWriteFont(headFont);
headStyle.setFillForegroundColor(IndexedColors.BLUE.getIndex());
// 设置内容样式
WriteCellStyle contentStyle = new WriteCellStyle();
WriteFont contentFont = new WriteFont();
contentFont.setFontHeightInPoints((short) 10);
contentStyle.setWriteFont(contentFont);
// 组合策略
HorizontalCellStyleStrategy strategy = new HorizontalCellStyleStrategy(headStyle, contentStyle);
String fileName = "带样式的用户数据.xlsx";
EasyExcel.write(fileName, UserData.class)
.registerWriteHandler(strategy)
.sheet("用户信息")
.doWrite(getUserList());
}
}
读 Excel
同步读取(适合小文件)
import com.alibaba.excel.EasyExcel;
public class SimpleRead {
public static void main(String[] args) {
String fileName = "用户数据.xlsx";
// 同步读取,直接返回 List
List<UserData> list = EasyExcel.read(fileName)
.head(UserData.class)
.sheet()
.doReadSync();
// 打印读取到的数据
list.forEach(System.out::println);
}
}
异步读取(推荐,适合大数据量)
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.ReadListener;
public class AsyncRead {
public static void main(String[] args) {
String fileName = "用户数据.xlsx";
EasyExcel.read(fileName, UserData.class, new ReadListener<UserData>() {
// 每读取一行,调用一次
@Override
public void invoke(UserData data, AnalysisContext context) {
System.out.println("读取到数据:" + data);
}
// 所有数据读取完成后的操作
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
System.out.println("所有数据读取完成!");
}
}).sheet().doRead();
}
}
批量处理读取(推荐方式)
public class BatchRead {
// 每批处理的条数
private static final int BATCH_COUNT = 100;
public static void main(String[] args) {
String fileName = "用户数据.xlsx";
EasyExcel.read(fileName, UserData.class, new ReadListener<UserData>() {
private List<UserData> batchList = new ArrayList<>(BATCH_COUNT);
@Override
public void invoke(UserData data, AnalysisContext context) {
batchList.add(data);
// 达到 BATCH_COUNT 时,批量处理
if (batchList.size() >= BATCH_COUNT) {
processBatch();
batchList.clear();
}
}
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
// 处理剩余数据
if (!batchList.isEmpty()) {
processBatch();
}
System.out.println("所有数据处理完成!");
}
private void processBatch() {
// 批量处理数据,比如批量插入数据库
System.out.println("批量处理 " + batchList.size() + " 条数据");
}
}).sheet().doRead();
}
}
高级用法
动态头(表头不固定时)
public class DynamicHeadWrite {
public static void main(String[] args) {
// 动态构建表头
List<List<String>> head = new ArrayList<>();
head.add(Arrays.asList("姓名", "基本信息")); // 合并单元格
head.add(Arrays.asList("年龄", "基本信息"));
head.add(Arrays.asList("邮箱", "联系方式"));
head.add(Arrays.asList("电话", "联系方式"));
// 准备数据
List<List<String>> data = new ArrayList<>();
data.add(Arrays.asList("张三", "25", "zhangsan@example.com", "13800138000"));
data.add(Arrays.asList("李四", "30", "lisi@example.com", "13900139000"));
String fileName = "动态表头.xlsx";
EasyExcel.write(fileName)
.head(head)
.sheet("数据")
.doWrite(data);
}
}
模板填充
public class TemplateFill {
public static void main(String[] args) {
String templateFile = "模板.xlsx";
String outputFile = "填充结果.xlsx";
// 准备填充数据
Map<String, Object> fillData = new HashMap<>();
fillData.put("name", "张三");
fillData.put("age", 25);
fillData.put("createDate", new Date());
// 填充单个对象
EasyExcel.write(outputFile)
.withTemplate(templateFile)
.sheet()
.doFill(fillData);
}
}
数据验证
public class DataValidation {
// 使用 @ExcelProperty 注解进行简单验证
@Data
public static class ValidatedData {
@ExcelProperty("必填字段")
@NotBlank(message = "不能为空")
private String requiredField;
@ExcelProperty("数字字段")
@Min(value = 0, message = "不能小于0")
@Max(value = 100, message = "不能大于100")
private Integer numberField;
@ExcelProperty("长度限制")
@Size(max = 10, message = "长度不能超过10")
private String limitedField;
}
}
性能优化建议
大数据量写入
public class LargeDataWrite {
public static void main(String[] args) {
String fileName = "大数据.xlsx";
EasyExcel.write(fileName, UserData.class)
.sheet("数据")
.doWrite(() -> {
// 数据分批获取,避免一次性加载到内存
for (int i = 0; i < 10000; i++) {
List<UserData> batch = getBatchData(i);
return batch;
}
return null;
});
}
}
内存优化配置
public class MemoryOptimized {
public static void main(String[] args) {
// 写入优化
EasyExcel.write(fileName, UserData.class)
.inMemory(false) // 使用文件缓存,减少内存使用
.sheet("数据")
.doWrite(dataList);
// 读取优化
EasyExcel.read(fileName, UserData.class, new ReadListener<UserData>() {
@Override
public void invoke(UserData data, AnalysisContext context) {
// 逐行处理,不加载全部到内存
processLine(data);
}
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
// 完成
}
})
.sheet()
.doRead();
}
}
常见问题解决
日期格式处理
@Data
public class DateDemo {
@ExcelProperty("日期")
@DateTimeFormat("yyyy年MM月dd日")
private Date date;
@ExcelProperty("时间")
@DateTimeFormat("yyyy-MM-dd HH:mm:ss")
private LocalDateTime localDateTime;
}
数字格式化
@Data
public class NumberDemo {
@ExcelProperty("金额")
@NumberFormat("#.##")
private Double money;
@ExcelProperty("百分比")
@NumberFormat("#%")
private Double percentage;
}
导入时忽略某些列
@Data
public class IgnoreColumnDemo {
@ExcelProperty("姓名")
private String name;
@ExcelProperty("年龄")
private Integer age;
@ExcelIgnore // 忽略这个字段
private String ignoreField;
@ExcelProperty(index = 3) // 指定列索引
private String otherField;
}
选择 EasyExcel 的场景:
- 需要处理大数据量 Excel(万级以上)
- 内存敏感的应用
- 需要高性能的 Excel 读写
- 想要简单易用的 API
注意事项:
- 尽量使用异步读取,避免 OOM
- 大数据量写入时,使用分批写入
- 注意文件路径和流资源的正确关闭
- 测试环境验证后再应用于生产
希望这个指南能帮助你快速上手 EasyExcel!如果你有具体的业务场景,可以告诉我,我可以提供更针对性的示例。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播