在处理Excel文件时,Java开发者常常需要依赖一些库来简化操作。阿里巴巴开源的EasyExcel是一个轻量级、高效的Excel读写工具,它能够显著提升开发效率,并减少内存占用。本文将详细介绍EasyExcel的核心功能和使用方法,帮助Java开发者更好地掌握这一强大的工具。
EasyExcel是阿里巴巴开源的一个基于SAX模式的Excel处理库,主要用于解决大文件读取时内存溢出的问题。与传统的Apache POI相比,EasyExcel在处理大文件时性能更优,因为它不会一次性将整个Excel文件加载到内存中,而是逐行解析数据。
在开始之前,我们需要引入EasyExcel依赖。以下是Maven配置示例:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.0.5</version>
</dependency>
确保你的项目中已经正确引入了上述依赖。
EasyExcel支持通过监听器的方式逐行读取Excel文件内容。以下是一个简单的示例:
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import java.util.ArrayList;
import java.util.List;
public class ExcelReadExample {
public static void main(String[] args) {
String fileName = "example.xlsx";
EasyExcel.read(fileName, DemoData.class, new AnalysisEventListener<DemoData>() {
private List<DemoData> dataList = new ArrayList<>();
@Override
public void invoke(DemoData data, AnalysisContext context) {
dataList.add(data);
System.out.println("解析到一条数据: " + data);
}
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
System.out.println("所有数据解析完成!");
}
}).sheet().doRead();
}
}
@Data
class DemoData {
@ExcelProperty("姓名")
private String name;
@ExcelProperty("年龄")
private Integer age;
}
sequenceDiagram participant Reader as EasyExcel Reader participant Listener as AnalysisEventListener participant Data as DemoData Reader->>Listener: 调用invoke方法传递一行数据 Listener->>Data: 创建并填充对象 loop 每一行数据 Reader->>Listener: 调用invoke方法 Listener->>Data: 处理数据 end Reader->>Listener: 所有数据解析完成后调用doAfterAllAnalysed
EasyExcel同样提供了便捷的API用于生成Excel文件。以下是一个写入示例:
import com.alibaba.excel.EasyExcel;
import java.util.ArrayList;
import java.util.List;
public class ExcelWriteExample {
public static void main(String[] args) {
String fileName = "output.xlsx";
List<DemoData> data = new ArrayList<>();
data.add(new DemoData("张三", 25));
data.add(new DemoData("李四", 30));
EasyExcel.write(fileName, DemoData.class).sheet("Sheet1").doWrite(data);
}
}
@Data
class DemoData {
@ExcelProperty("姓名")
private String name;
@ExcelProperty("年龄")
private Integer age;
}
在读取Excel文件时,我们可以通过实现VerifyHandler
接口对数据进行校验。例如,检查年龄是否为正数。
@Override
public boolean verify(CellData cellData, ExcelContentProperty excelContentProperty, GlobalConfiguration globalConfiguration, Optional<Object> cachedObject) {
if (cellData.getType() == CellDataTypeEnum.NUMBER) {
double value = ((NumberCellData) cellData).getNumberValue();
return value > 0; // 年龄必须大于0
}
return false;
}
EasyExcel允许开发者自定义单元格样式,例如设置字体、背景色等。
WriteCellStyle headWriteCellStyle = new WriteCellStyle();
headWriteCellStyle.setFillForegroundColor(IndexedColors.YELLOW.getIndex());
headWriteCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);
WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
contentWriteCellStyle.setWrapped(true);
HorizontalAlign horizontalAlign = HorizontalAlign.CENTER;
headWriteCellStyle.setHorizontalAlignment(horizontalAlign);
contentWriteCellStyle.setHorizontalAlignment(horizontalAlign);
// 设置表头样式
HeadStyleStrategy headStyleStrategy = new DefaultHeadStyleStrategy(headWriteCellStyle);
// 设置内容样式
AbstractCellStyleStrategy contentStyleStrategy = new DefaultContentStyleStrategy(contentWriteCellStyle);
EasyExcel.write(fileName, DemoData.class)
.registerWriteHandler(headStyleStrategy)
.registerWriteHandler(contentStyleStrategy)
.sheet("Sheet1")
.doWrite(data);
如何处理多Sheet文件?
sheet(int sheetNo)
或sheet(String sheetName)
指定具体的Sheet。如何处理复杂的数据结构?
如何优化性能?