EasyExcel自定义转换器编写指南

2025-04发布20次浏览

在使用阿里巴巴开源的EasyExcel进行Excel文件读写时,自定义转换器是一项非常重要的功能。通过自定义转换器,可以灵活地处理复杂的业务逻辑,例如将字符串转换为特定对象、格式化日期、处理枚举值等。本文将详细介绍如何编写EasyExcel的自定义转换器,并提供实际代码示例。


一、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 单元格数据。

二、编写自定义转换器的步骤

1. 创建自定义转换器类

首先,创建一个类并实现 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);
    }
}

2. 注册自定义转换器

要让 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;
    }
}

三、自定义转换器的实际应用

示例 1:处理枚举类型

假设有一个性别枚举类 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 的自定义转换器,并提供了具体的代码示例和实际应用场景。自定义转换器不仅能够满足复杂的数据类型转换需求,还能显著提升代码的可维护性和灵活性。