MS-Jing opened a new issue, #1006:
URL: https://github.com/apache/fesod/issues/1006

   # 希望添加导入导出枚举类支持
   我们有时候需要某个字段是枚举类型的,例如数据库存的是1 而真实的含义可能是正常,当我导入导出的时候 需要的是真实的含义。
   如果目前我们可以这样来操作:
   用户可以自定义一个枚举接口,那么所有的需要导入导出的枚举字段实现该接口
   ```java
   /**
    * @author luojing
    * @since 2026/8/11 10:33
    * The enumeration that implements this interface has the ability to import 
and export enumerations.
    */
   public interface IEnum {
   
       String getLabel();
   }
   
   @AllArgsConstructor
   @Getter
   public enum UserStatus implements IEnum {
   
       NORMAL(1, "正常"),
       LOCKING(2, "锁定");
   
   
       private final Integer value;
       private final String desc;
   
       @Override
       public String getLabel() {
           return desc;
       }
   }
   ```
   
   再自定一个这个枚举类型的转换器
   ```java
   package cn.idev.excel.converters.enums;
   
   import cn.idev.excel.converters.Converter;
   import cn.idev.excel.enums.CellDataTypeEnum;
   import cn.idev.excel.enums.IEnum;
   import cn.idev.excel.metadata.GlobalConfiguration;
   import cn.idev.excel.metadata.data.ReadCellData;
   import cn.idev.excel.metadata.data.WriteCellData;
   import cn.idev.excel.metadata.property.ExcelContentProperty;
   
   import java.util.*;
   import java.util.stream.Collectors;
   
   /**
    * @author luojing
    * @description: enum converter
    * @since 2026/8/11 10:36
    */
   public class IEnumConverter implements Converter<IEnum> {
   
       private static final Map<Class<?>, List<IEnum>> enumCache = new 
HashMap<>();
   
       @Override
       public Class<?> supportJavaTypeKey() {
           return IEnum.class;
       }
   
       @Override
       public CellDataTypeEnum supportExcelTypeKey() {
           return CellDataTypeEnum.STRING;
       }
   
       @Override
       public WriteCellData<?> convertToExcelData(IEnum value, 
ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) 
throws Exception {
           if (value != null) {
               return new WriteCellData<>(value.getLabel());
           }
           return new WriteCellData<>();
       }
   
       @Override
       public IEnum convertToJavaData(ReadCellData<?> cellData, 
ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) 
throws Exception {
           Class<?> type = contentProperty.getField().getType();
           if (!enumCache.containsKey(type)) {
               Object[] enumConstants = type.getEnumConstants();
               List<IEnum> iEnumList = 
Arrays.stream(enumConstants).map(enumConstant -> (IEnum) 
enumConstant).collect(Collectors.toList());
               enumCache.put(type, iEnumList);
           }
           List<IEnum> iEnumList = enumCache.getOrDefault(type, 
Collections.emptyList());
           for (IEnum iEnum : iEnumList) {
               if (iEnum.getLabel().equals(cellData.getStringValue())) {
                   return iEnum;
               }
           }
           return null;
       }
   }
   ```
   
   最后在我们需要导出的时候,将导出的类字段上指名这个转换器
   ```java
   @Data
   public static class UserInfo {
       /**
        * 用户名
        */
       @ExcelProperty("用户名")
       private String userName;
   
       /**
        * 用户状态  这里指名用IEnumConverter的转换器
        */
       @ExcelProperty(value = "用户状态", converter = IEnumConverter.class)
       private UserStatus userStatus;
   }
   ```
   这样在我们导出的时候就可以直接用了
   ```java
       @Test
       public void testIEnumConverter() {
           String fileName = System.getProperty("user.dir") + "/iEnumConverter" 
+ System.currentTimeMillis() + ".xlsx";
   
           // 写出枚举类型字段
           FastExcel.write(fileName)
               .head(UserInfo.class)
   //            .registerConverter(new IEnumConverter())
               .sheet()
               .doWrite(testDataList());
   
           // 读取枚举类型字段
           List<UserInfo> list = FastExcel.read(fileName)
   //            .registerConverter(new IEnumConverter())
               .head(UserInfo.class)
               .sheet()
               .doReadSync();
           System.out.println(list);
       }
   ```
   
   # 但是
   这并不通用,这意味着我每个枚举字段都需要指名`@ExcelProperty(converter = IEnumConverter.class)` 
或者手动注册转换器`registerConverter(new IEnumConverter())`
   而且我看了`CustomSheetWriteHandler` 如果我们可以新增这个特性,那么我们可以对枚举类型的字段导入导出做一个下拉框限制:
   
   # 解决方案(需要提pr)
   + 修改`ConverterKeyBuild#buildKey`方法,让枚举字段可以映射到转换器:
   ```java
   public static ConverterKey buildKey(Class<?> clazz, CellDataTypeEnum 
cellDataTypeEnum) {
       Class<?> boxingClass = BOXING_MAP.get(clazz);
       if (boxingClass != null) {
           return new ConverterKey(boxingClass, cellDataTypeEnum);
       }
       if (clazz == IEnum.class || (clazz.isEnum() && 
IEnum.class.isAssignableFrom(clazz))) {
           // clazz equals IEnum.class or clazz is enum and IEnum is assignable 
from clazz
           return new ConverterKey(IEnum.class, cellDataTypeEnum);
       }
       return new ConverterKey(clazz, cellDataTypeEnum);
   }
   ```
   + 将`IEnumConverter` 注册到`DefaultConverterLoader`中
   + 再次启动,无需每个枚举字段指名转换器和无需手动注册枚举转换器
   ```java
     @Test
     public void testIEnumConverter() {
         String fileName = System.getProperty("user.dir") + 
"/iEnumConverter.xlsx";
   
         // 写出枚举类型字段
         FastExcel.write(fileName)
             .head(UserInfo.class)
             .sheet()
             .doWrite(testDataList());
   
         // 读取枚举类型字段
         List<UserInfo> list = FastExcel.read(fileName)
             .head(UserInfo.class)
             .sheet()
             .doReadSync();
         System.out.println(list);
     }
   ```
   
   _Originally posted by @MS-Jing in 
https://github.com/apache/fesod/discussions/1005_


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to