在使用阿里巴巴开源的EasyExcel进行Excel文件读写时,自定义转换器是一项非常重要的功能。通过自定义转换器,可以灵活地处理复杂的业务逻辑,例如将字符串转换为特定对象、格式化日期、处理枚举值等。本文将详细介绍如何编写EasyExcel的自定义转换器,并提供实际代码示例。
EasyExcel 是一个轻量级的 Excel 处理库,专注于解决大 Excel 文件的读写问题。它提供了内置的数据类型转换器,但当遇到复杂场景(如需要将字符串转换为自定义对象或特殊格式)时,就需要使用自定义转换器。
自定义转换器的核心是实现 org.alibaba.excel.converters.Converter
接口,该接口定义了两个核心方法:
convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration)
:将 Excel 单元格数据转换为 Java 对象。convertToExcelData(Object javaData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration)
:将 Java 对象转换为 Excel 单元格数据。首先,创建一个类并实现 Converter<T>
接口,其中 <T>
表示目标数据类型。
import org.alibaba.excel.converters.Converter;
import org.alibaba.excel.metadata.data.WriteCellData;
import org.alibaba.excel.metadata.property.ExcelContentProperty;
import org.alibaba.excel.metadata.property.ExcelField;
import org.alibaba.excel.metadata.property.ExcelHeadProperty;
import org.alibaba.excel.metadata.property.ExcelIgnoreUnannotated;
import org.alibaba.excel.util.DateUtils;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
public class LocalDateConverter implements Converter<LocalDate> {
@Override
public Class<?> supportJavaTypeKey() {
return LocalDate.class;
}
@Override
public WriteCellData<?> convertToExcelData(LocalDate localDate, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {
if (localDate == null) {
return new WriteCellData<>(null);
}
// 定义日期格式
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
return new WriteCellData<>(localDate.format(formatter));
}
@Override
public LocalDate convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {
if (cellData == null || cellData.getStringValue() == null) {
return null;
}
// 解析日期字符串
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
return LocalDate.parse(cellData.getStringValue(), formatter);
}
}
要让 EasyExcel 使用自定义转换器,可以通过以下两种方式注册:
在实体类字段上使用 @ExcelProperty
注解,并通过 converter
属性指定自定义转换器。
import com.alibaba.excel.annotation.ExcelProperty;
public class User {
@ExcelProperty(converter = LocalDateConverter.class)
private LocalDate birthday;
// Getter 和 Setter
public LocalDate getBirthday() {
return birthday;
}
public void setBirthday(LocalDate birthday) {
this.birthday = birthday;
}
}
如果希望某个转换器对所有字段生效,可以在全局配置中注册。
import org.alibaba.excel.write.builder.ExcelWriterBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.HashMap;
import java.util.Map;
@Configuration
public class ExcelConfig {
@Bean
public Map<Class<?>, Converter<?>> customConverters() {
Map<Class<?>, Converter<?>> converters = new HashMap<>();
converters.put(LocalDate.class, new LocalDateConverter());
return converters;
}
}
假设有一个性别枚举类 GenderEnum
,我们需要将其与 Excel 中的字符串进行互相转换。
public enum GenderEnum {
MALE("男"),
FEMALE("女");
private final String name;
GenderEnum(String name) {
this.name = name;
}
public String getName() {
return name;
}
public static GenderEnum fromName(String name) {
for (GenderEnum gender : GenderEnum.values()) {
if (gender.getName().equals(name)) {
return gender;
}
}
return null;
}
}
import org.alibaba.excel.converters.Converter;
import org.alibaba.excel.metadata.data.WriteCellData;
import org.alibaba.excel.metadata.property.ExcelContentProperty;
public class GenderEnumConverter implements Converter<GenderEnum> {
@Override
public Class<?> supportJavaTypeKey() {
return GenderEnum.class;
}
@Override
public WriteCellData<?> convertToExcelData(GenderEnum genderEnum, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {
if (genderEnum == null) {
return new WriteCellData<>(null);
}
return new WriteCellData<>(genderEnum.getName());
}
@Override
public GenderEnum convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {
if (cellData == null || cellData.getStringValue() == null) {
return null;
}
return GenderEnum.fromName(cellData.getStringValue());
}
}
以下是自定义转换器的工作流程图:
flowchart TD A[Excel单元格数据] --> B{是否需要转换?} B --是--> C[调用convertToJavaData] C --> D[Java对象] D --> E[业务逻辑处理] F[Java对象] --> G[调用convertToExcelData] G --> H[Excel单元格数据]
通过本文,我们详细介绍了如何编写 EasyExcel 的自定义转换器,并提供了具体的代码示例和实际应用场景。自定义转换器不仅能够满足复杂的数据类型转换需求,还能显著提升代码的可维护性和灵活性。