在使用阿里巴巴开源的EasyExcel进行Excel文件读写时,单元格注解(如@ExcelProperty
)是简化代码逻辑、提高开发效率的重要工具。本文将详细解析EasyExcel中的单元格注解功能,并通过具体示例说明如何利用这些注解优化代码结构。
EasyExcel是一个基于Java语言的轻量级Excel读写库,它专注于解决大数据量场景下的性能问题。与传统的Apache POI相比,EasyExcel通过流式读取的方式显著降低了内存占用,同时提供了丰富的注解支持,让开发者能够以更简洁的代码实现复杂的Excel处理需求。
@ExcelProperty
@ExcelProperty
是EasyExcel中最常用的注解之一,主要用于指定实体类字段与Excel表头之间的映射关系。以下是该注解的主要功能和参数:
@ExcelProperty
可以通过指定表头名称或列索引来完成字段映射。例如:
public class UserData {
@ExcelProperty("姓名")
private String name;
@ExcelProperty("年龄")
private Integer age;
// Getter and Setter
}
上述代码中,name
字段对应Excel中的“姓名”列,age
字段对应“年龄”列。
如果Excel文件没有明确的表头,也可以通过列索引(从0开始)来映射字段:
public class UserData {
@ExcelProperty(index = 0)
private String name;
@ExcelProperty(index = 1)
private Integer age;
// Getter and Setter
}
对于包含多级表头的Excel文件,@ExcelProperty
支持通过数组形式指定路径:
public class UserData {
@ExcelProperty(value = {"个人信息", "姓名"})
private String name;
@ExcelProperty(value = {"个人信息", "年龄"})
private Integer age;
// Getter and Setter
}
在这种情况下,Excel的表头结构可能如下:
| 个人信息 | | 其他信息 |
| --------------- | -------- | ------------- |
| 姓名 | 年龄 | 其他字段 |
除了简单的字段映射外,@ExcelProperty
还支持数据格式化和类型转换,这使得开发者可以更加灵活地处理Excel中的数据。
通过converter
属性,可以为字段指定自定义的转换器。例如,将日期字符串转换为LocalDate
类型:
public class UserData {
@ExcelProperty(value = "出生日期", converter = LocalDateConverter.class)
private LocalDate birthDate;
// Getter and Setter
}
// 自定义转换器
public class LocalDateConverter implements ReadConverter<LocalDate>, WriteConverter<LocalDate> {
private DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
@Override
public LocalDate convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception {
return LocalDate.parse(cellData.getStringValue(), formatter);
}
@Override
public CellData convertToExcelData(LocalDate value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception {
return new CellData(value.format(formatter));
}
}
当字段为枚举类型时,可以通过converter
指定枚举值的转换规则。例如:
public enum Gender {
MALE("男"),
FEMALE("女");
private final String description;
Gender(String description) {
this.description = description;
}
public String getDescription() {
return description;
}
}
public class UserData {
@ExcelProperty(value = "性别", converter = GenderConverter.class)
private Gender gender;
// Getter and Setter
}
// 枚举转换器
public class GenderConverter implements ReadConverter<Gender>, WriteConverter<Gender> {
@Override
public Gender convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception {
String value = cellData.getStringValue();
for (Gender gender : Gender.values()) {
if (gender.getDescription().equals(value)) {
return gender;
}
}
return null;
}
@Override
public CellData convertToExcelData(Gender value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception {
return new CellData(value.getDescription());
}
}
在某些场景下,Excel表头可能不是固定的,而是根据业务逻辑动态生成的。此时可以通过实现DynamicHeadReadListener
接口来动态设置表头映射关系。
classDiagram class UserData { +String name +Integer age } class DynamicHeadReadListener { +Listhead +void invoke(Object data, AnalysisContext context) +void doAfterAllAnalysed(AnalysisContext context) } UserData --|> DynamicHeadReadListener: used by
动态表头读取的基本流程如下:
通过使用@ExcelProperty
等单元格注解,EasyExcel极大地简化了Excel文件的读写操作。无论是基本的字段映射、数据格式化,还是复杂的多级表头和动态表头支持,都可以通过简单的注解配置完成。这种设计不仅提高了代码的可读性和可维护性,还减少了手动编写复杂解析逻辑的工作量。