编写一个简单的EasyExcel枚举类转换器

最近项目中用到了阿里的EasyExcel,一个简单方便读写excel的工具。

需求场景

在项目中会定义一些枚举类来保存一些状态值,在存储进数据库时保存的是code,而我们在生成excel时需要展示对应的值。

代码实现

需要写入excel的对象

1
2
3
4
5
6
7
8
9
@Data
public class TestExcel {

/**
* 状态
*/
@ExcelProperty(value = "状态",converter = StatusEnumConvert.class)
private String status;
}

枚举类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
public enum StatusEnum {
WAIT_COMMIT("1","待提交"),
WAIT_AUDIT("2","待审核"),
AUDITED("3","已审核"),
RETURNED("4","已退回");

private final String code;
private final String info;

StatusEnum(String code, String info)
{
this.code = code;
this.info = info;
}

public String getCode()
{
return code;
}

public String getInfo()
{
return info;
}

/**
* 根据code获取info
*/
public static String getInfoByCode(String code){
for (StatusEnum statusEnum : StatusEnum.values()) {
if (statusEnum.getCode().equals(code)){
return statusEnum.getInfo();
}
}
return null;
}

public static String getCodeByInfo(String info){
for (StatusEnum statusEnum : StatusEnum.values()) {
if (statusEnum.getInfo().equals(info)){
return statusEnum.getCode();
}
}
return null;
}
}

转换器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class StatusEnumConvert implements Converter<String> {

@Override
public Class supportJavaTypeKey() {
return String.class;
}

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

@Override
public String convertToJavaData(CellData cellData, ExcelContentProperty excelContentProperty, GlobalConfiguration globalConfiguration) throws Exception {
String info = cellData.toString();
return StatusEnum.getCodeByInfo(info);
}

@Override
public CellData convertToExcelData(String s, ExcelContentProperty excelContentProperty, GlobalConfiguration globalConfiguration) throws Exception {
return new CellData(Objects.requireNonNull(StatusEnum.getInfoByCode(s)));
}
}

应网友反馈,使用注解和反射改进了转换器,提高复用性;

改进后

先自定义一个注解

1
2
3
4
5
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface TargetEnum {
Class<? extends Enum> targetEnum();
}

需要转换的枚举类

不再需要getCodeByInfo()getInfoById()方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public enum StatusEnum implements GetEnum {
WAIT_COMMIT("1","待提交"),
WAIT_AUDIT("2","待审核"),
AUDITED("3","已审核"),
RETURNED("4","已退回");

private final String code;
private final String info;

StatusEnum(String code, String info)
{
this.code = code;
this.info = info;
}

public String getCode()
{
return code;
}

public String getInfo()
{
return info;
}
}

需要写入excel的对象

1
2
3
4
5
6
7
@Data
public class TestExcel {
//加上自定义注解,并写上对应的枚举类作为参数
@TargetEnum(targetEnum = StatusEnum.class)
@ExcelProperty(value = "状态",converter = StatusEnumConverter.class)
private String status;
}

修改后的转换器

利用反射获取字段上注解的枚举类型,然后调用get..()方法取值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
public class StatusEnumConverter implements Converter<String> {
@Override
public Class supportJavaTypeKey() {
return String.class;
}

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

@Override
public String convertToJavaData(CellData cellData, ExcelContentProperty excelContentProperty, GlobalConfiguration globalConfiguration) throws Exception {
String code="";
String info = cellData.toString();
Field field = excelContentProperty.getField();
TargetEnum annotation = field.getDeclaredAnnotation(TargetEnum.class);
Class clazz = annotation.targetEnum();
Object[] enumConstants = clazz.getEnumConstants();
Method getInfo = clazz.getMethod("getInfo");
Method getCode = clazz.getMethod("getCode");
for (Object enumConstant : enumConstants) {
if (getInfo.invoke(enumConstant, null).equals(info)) {
code = (String) getCode.invoke(enumConstant, null);
break;
}
}
return code;
}

@Override
public CellData convertToExcelData(String s, ExcelContentProperty excelContentProperty, GlobalConfiguration globalConfiguration) throws Exception {
String info = "";
Field field = excelContentProperty.getField();
TargetEnum annotation = field.getDeclaredAnnotation(TargetEnum.class);
Class clazz = annotation.targetEnum();
Object[] enumConstants = clazz.getEnumConstants();
Method getInfo = clazz.getMethod("getInfo");
Method getCode = clazz.getMethod("getCode");
for (Object enumConstant : enumConstants) {
if (getCode.invoke(enumConstant, null).equals(s)) {
info = (String) getInfo.invoke(enumConstant, null);
break;
}
}
return new CellData(info);
}
}

调用

1
EasyExcel.write(filePath,TestExcel.class).sheet("枚举转换器").doWrite(dataList());

效果