在处理百万行级别的Excel文件时,传统的Excel处理方式(如Apache POI)可能会面临内存占用过高、性能低下等问题。而阿里巴巴开源的EasyExcel框架因其轻量级、高效和易用的特点,成为了解决这一问题的理想工具。以下是使用EasyExcel处理大规模Excel文件的具体方法与注意事项。
EasyExcel是基于Java语言开发的一个简单高效的Excel处理库,它通过流式读取的方式显著降低了内存占用。相比传统的Excel处理库(如Apache POI),EasyExcel更适合处理超大数据量的场景,同时提供了丰富的API支持。
首先,在项目的pom.xml
中引入EasyExcel的Maven依赖:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.0.5</version> <!-- 请根据实际需求选择版本 -->
</dependency>
为了将Excel中的数据映射到Java对象中,需要定义一个对应的实体类。例如:
public class UserData {
@ExcelProperty("姓名") // 对应Excel列名
private String name;
@ExcelProperty("年龄")
private Integer age;
@ExcelProperty("邮箱")
private String email;
// Getter和Setter方法
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
对于百万行级别的Excel文件,直接一次性加载所有数据到内存中会导致OOM(Out of Memory)。因此,推荐使用EasyExcel的分页读取或逐行读取功能。
创建一个继承自AnalysisEventListener
的监听器类,用于处理每一行的数据。
public class ExcelListener extends AnalysisEventListener<UserData> {
private List<UserData> dataList = new ArrayList<>();
@Override
public void invoke(UserData data, AnalysisContext context) {
// 每读取一行数据都会调用此方法
dataList.add(data);
if (dataList.size() >= 1000) { // 达到一定数量后进行批量处理
saveData(); // 调用业务逻辑保存数据
dataList.clear(); // 清空缓存列表
}
}
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
// 所有数据解析完成后调用
if (!dataList.isEmpty()) {
saveData(); // 处理剩余未保存的数据
}
}
private void saveData() {
// 在这里实现具体的业务逻辑,比如将数据插入数据库
System.out.println("保存了 " + dataList.size() + " 条数据");
}
}
通过EasyExcel.read
方法结合监听器完成文件读取:
public class ExcelReader {
public static void main(String[] args) {
String fileName = "path/to/large_file.xlsx"; // Excel文件路径
EasyExcel.read(fileName, UserData.class, new ExcelListener())
.sheet() // 默认读取第一个工作表
.doRead();
}
}
当需要生成大文件时,可以利用EasyExcel的分页写入功能避免内存溢出。
创建一个Iterator
或List
作为数据源:
public class LargeDataGenerator implements Iterator<UserData> {
private int count = 0;
@Override
public boolean hasNext() {
return count < 1000000; // 假设生成100万条数据
}
@Override
public UserData next() {
UserData data = new UserData();
data.setName("User" + count);
data.setAge(20 + count % 50);
data.setEmail("user" + count + "@example.com");
count++;
return data;
}
}
使用EasyExcel.write
方法将数据写入Excel文件:
public class ExcelWriter {
public static void main(String[] args) {
String fileName = "path/to/output_file.xlsx";
EasyExcel.write(fileName, UserData.class)
.sheet("Sheet1")
.doWrite(new LargeDataGenerator());
}
}
-Xmx4g
)。EasyExcel以其高效的流式读写机制,为处理百万行级别的Excel文件提供了强大支持。通过合理设计监听器和数据提供器,可以轻松应对大规模数据场景下的性能挑战。