EasyExcel 自定义转换器、自定义导出枚举类替换,完整代码+详细注释说明

这是一个基于Easyexcel通过注解的方式,实现在导入导出的时候,按照指定的字段和枚举类,进行字典值映射转换的工具。

不通过枚举类、而是直接在注解中写替换枚举的,请看另外一篇文章:EasyExcel 自定义转换器、自定义导出字典映射替换、满足条件内容增加样式,完整代码+详细注释说明

以下正文:

1.定义枚举类


/**
 * @Description:
 * @author: CloverAn
 * @email: 285135288@qq.com
 * @created: 2024/08/14 15:01
 */
public enum SexEunm implements DoGetEnum<String> {
  
    /*需要修改的内容 - BEGIN*/
    MAN("0-1", "男"),
    WOMAN("1-2", "女");
    /*需要修改的内容 - END*/

    final String enumKey;
    final String enumDesc;

    SexEunm(String enumKey, String enumDesc) {
        this.enumKey = enumKey;
        this.enumDesc = enumDesc;
    }

    /**
     * 根据key获取value值
     *
     * @param key
     * @return
     */
    public SexEunm getEnumByKey(String key) {
        for (SexEunm sexEunm : SexEunm.values()) {
            if (sexEunm.enumKey.equals(key)) {
                return sexEunm;
            }
        }
        return null;
    }

    /**
     * 根据value获取枚举key值
     *
     * @param value
     * @return
     */
    public SexEunm getEnumByValue(String value) {
        for (SexEunm sexEunm : SexEunm.values()) {
            if (sexEunm.enumDesc.equals(value)) {
                return sexEunm;
            }
        }
        return null;
    }

    @Override
    public String getValueByKey(String key) {
        SexEunm sexEunm = getEnumByKey(key);
        return sexEunm == null ? null : sexEunm.enumDesc;
    }

    @Override
    public String getKeyByValue(String value) {
        SexEunm sexEunm = getEnumByValue(enumDesc);
        return sexEunm == null ? null : sexEunm.enumKey;
    }
}

注意:
1.定义了通过key获取value 和 通过value获取key 的两个方法。这两个方法必须在自己写的类里面必须要有。此外,对于大多数情况来说,只需要修改内容里面的枚举值即可,代码里面做了标识,整体不需要改动。
2.这里继承了一个DoGetEnum类,并实现了其中的两个方法。原因是太菜 ,没找到通过反射执行获取对应内置函数的办法,因此通过外部接口的方式,获取对应函数方法,并执行获取数据。接口代码如下:

/**
 * @Description: converter中反射获取的查询数据的方法,
 * 对反射应用不熟,没有想到办法直接写在枚举类中,所以写一个接口,让枚举类实现。
 * @Creator: CloverAn
 * @Date: 2024/8/14 17:22
 */
public interface DoGetEnum<T> {

    /**
     * 根据字典key值获取对应value值,主要用于导出时字典映射转换
     *
     * @param key 字典值
     * @return 描述
     */
    String getValueByKey(T key);

    /**
     * 根据value获取对应字典key值,主要用于导入时字典映射转换
     *
     * @param value 描述
     * @return 字典值
     */
    T getKeyByValue(String value);
}

2.定义自定义注解

import java.lang.annotation.*;
/**
 * @Description: 字典映射转换自定义注解
 * @Creator: CloverAn
 * @Date: 2024/8/14 17:22
 */
@Documented
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ExcelEnumValue {
    Class<? extends Enum<?>> value();
}

这里的枚举类,属性接收的是一个枚举类的对象。

3.重写EasyExcel转换器接口,对excel读和写方法都进行自定义


import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.GlobalConfiguration;
import com.alibaba.excel.metadata.data.ReadCellData;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.metadata.property.ExcelContentProperty;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @Description: 自定义converter
 * @Creator: CloverAn
 * @Date: 2024/8/14 17:22
 */
public class ExcelEnumValueConverter implements Converter<Object> {

    @Override
    public Class<?> supportJavaTypeKey() {
        return Object.class;
    }

    @Override
    public CellDataTypeEnum supportExcelTypeKey() {
        return CellDataTypeEnum.STRING;
    }

    @Override
    public WriteCellData<?> convertToExcelData(Object value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {
        ExcelEnumValue enumValue = contentProperty.getField().getAnnotation(ExcelEnumValue.class);
        Class<?> enumClass = enumValue.value();
        Object enumConstant = enumClass.getEnumConstants()[0];
        Method method = null;
        Object invoke = null;
        try {
            //获取枚举类中的方法并执行,以期望获取到对应的value值数据
            method = enumClass.getDeclaredMethod("getValueByKey", Object.class);
            invoke = method.invoke(enumConstant, value);
        } catch (NoSuchMethodException e) {
            //抛出getValueByKey方法未找到异常
        } catch (InvocationTargetException | IllegalAccessException e) {
            //抛出getValueByKey方法调用失败异常
        }

        //Method method = null;
        //try {
        //    method = enumClass.getDeclaredMethod("getValueByKey", Object.class);
        //} catch (NoSuchMethodException e) {
        //    //抛出getValueByKey方法未找到异常
        //}
        //Object invoke = null;
        //try {
        //    invoke = method.invoke(enumConstant, value);
        //} catch (Exception e) {
        //    //抛出getValueByKey方法调用失败异常
        //}

        //注意,当枚举类中没有对应的key时,或者对应key的value是null时,invoke会返回null,此时会出现空指针。
        if (invoke == null) {
            invoke = "未找到指定key对应的value值";
        }
        return new WriteCellData<>(invoke.toString());
    }

    @Override
    public Object convertToJavaData(ReadCellData<?> cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception {
        String stringValue = cellData.getStringValue();
        ExcelEnumValue enumValue = contentProperty.getField().getAnnotation(ExcelEnumValue.class);
        Class<?> enumClass = enumValue.value();
        Object enumConstant = enumClass.getEnumConstants()[0];
        Method method = null;
        Object invoke = null;
        try {
            //获取枚举类中的方法并执行,以期望获取到对应的key值数据
            method = enumClass.getDeclaredMethod("getKeyByValue", String.class);
            invoke = method.invoke(enumConstant, stringValue);
        } catch (NoSuchMethodException e) {
            try {
                //获取枚举类中的方法并执行,以期望获取到对应的key值数据
                method = enumClass.getDeclaredMethod("getKeyByValue", Object.class);
                invoke = method.invoke(enumConstant, stringValue);
            } catch (NoSuchMethodException ex) {
                //抛出getKeyByValue方法未找到异常
            }
        }

        //Method method = null;
        //try {
        //    method = enumClass.getDeclaredMethod("getKeyByValue", String.class);
        //} catch (NoSuchMethodException e) {
        //    try {
        //        method = enumClass.getDeclaredMethod("getKeyByValue", Object.class);
        //    } catch (NoSuchMethodException ex) {
        //        //抛出getKeyByValue方法未找到异常
        //    }
        //}
        //Object invoke = null;
        //try {
        //    invoke = method.invoke(enumConstant, stringValue);
        //} catch (Exception e) {
        //    //抛出getKeyByValue方法调用失败异常
        //}

        //注意,当枚举类中没有对应的value时,或者对应value的key是null时,invoke会返回null,此时会出现空指针。
        if (invoke == null) {
            invoke = "未找到指定value对应的key值";
        }
        return invoke;
    }

}

1.原理就是,通过获取注解上传递进来的枚举类,通过反射获取类中的方法,并执行对应的方法获取数据。
2.这里可以做调整,并改为获取到执行内容后,进行其他的业务逻辑,比如添加样式、业务逻辑等。

4.测试实体类


import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;

/**
 * @Description:
 * @author: CloverAn
 * @email: 
 * @created: 2024/08/14 14:59
 */
@Data
public class SexEntity {
    @ExcelProperty(value = "性别",converter = ExcelEnumValueConverter.class)
    @ExcelEnumValue(SexEunm.class)
    String sex;
}

这里就简单模拟了。这时候导入或者导出的时候,对应的值会根据枚举值进行替换。

  • 7
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CloverAn

如果文章对你有帮助,感谢支持!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值