希望添加导入导出枚举类支持
我们有时候需要某个字段是枚举类型的,例如数据库存的是1 而真实的含义可能是正常,当我导入导出的时候 需要的是真实的含义。
如果目前我们可以这样来操作:
用户可以自定义一个枚举接口,那么所有的需要导入导出的枚举字段实现该接口
/**
* @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;
}
}
再自定一个这个枚举类型的转换器
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;
}
}
最后在我们需要导出的时候,将导出的类字段上指名这个转换器
@Data
public static class UserInfo {
/**
* 用户名
*/
@ExcelProperty("用户名")
private String userName;
/**
* 用户状态 这里指名用IEnumConverter的转换器
*/
@ExcelProperty(value = "用户状态", converter = IEnumConverter.class)
private UserStatus userStatus;
}
这样在我们导出的时候就可以直接用了
@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方法,让枚举字段可以映射到转换器:
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中
- 再次启动,无需每个枚举字段指名转换器和无需手动注册枚举转换器
@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 #1005
希望添加导入导出枚举类支持
我们有时候需要某个字段是枚举类型的,例如数据库存的是1 而真实的含义可能是正常,当我导入导出的时候 需要的是真实的含义。
如果目前我们可以这样来操作:
用户可以自定义一个枚举接口,那么所有的需要导入导出的枚举字段实现该接口
再自定一个这个枚举类型的转换器
最后在我们需要导出的时候,将导出的类字段上指名这个转换器
这样在我们导出的时候就可以直接用了
但是
这并不通用,这意味着我每个枚举字段都需要指名
@ExcelProperty(converter = IEnumConverter.class)或者手动注册转换器registerConverter(new IEnumConverter())而且我看了
CustomSheetWriteHandler如果我们可以新增这个特性,那么我们可以对枚举类型的字段导入导出做一个下拉框限制:解决方案(需要提pr)
ConverterKeyBuild#buildKey方法,让枚举字段可以映射到转换器:IEnumConverter注册到DefaultConverterLoader中Originally posted by @MS-Jing in #1005