EasyExcel自定义Converter全局加载器以及加载Converter的个人总结
·
converter三种加载方式以及注意事项
-
在需要转换的字段上的@ExcelProperty注解上添加converter属性
@ExcelProperty(value = "创建时间", index = 3, converter = LocalDateTimeConverter.class) private LocalDateTime createTime;
-
优点:此种方式只需在每个需要转换的字段上添加converter即可
-
缺点:如果有很多类,每个类中有很多需要单独转换的字段要写很多次就尴尬了!
-
适用场景:任何场景
-
-
在创建ExcelWriterBuilder时候为这次操作单独加载转换器
EasyExcel.write(response.getOutputStream(), UserExport.class).registerConverter(new LocalDateTimeConverter()).sheet("test").doWrite(list);
-
优点:此种方式只要在每个导入导出的方法上都单独加载转换器,不用在每个需要转换的字段上都添加converter了,一定程度上可以减少我们的工作量
-
缺点:只在本方法中有效,其他方法无效,如果有很多不同的导入导出方法就又尴尬了!
-
适用场景:适用于LocalDateTimeConverter场景,但是如果要是SexConverter场景就不适合!因为前者是LocalDateTime与String之间的转换,后者它的本质是Integer与String互相转换,因为String字段可以代表年龄、性别、等信息,所以没法转换,不知道我描述的是否清楚?
-
-
自定义全局加载器CustomerDefaultConverterLoader
-
优点:此种方式可以全局配置Converter,一劳永逸!配置完之后不用再单独修改字段或者修改方法,可以理解为EasyExcel从现在支持LocalDateTime啦!
-
缺点:只能添加特殊的Converter
-
适用场景:与第二种场景一样!
切记SexConverter不可放到全局加载器中,不信你试试。。。试过之后你就理解我为什么写这么多文字去介绍他们的适用场景了
-
总结:如果需要LocalDateTime做转换就用第三种直接放到全局加载器中,如果需要sex做转换就用第一种!可以并存,优先级:第一种 > 第二种 > 第三种
EasyExcel的converter加载流程
- EasyExcel的全局Converter加载器类:
DefaultConverterLoader
,那我们就来debug看看是怎么进行转换的 - 大体流程就是: 读取全局加载器类 -> 写入的时候判断该字段上是否制定Converter,有则取之,没有的话 -> 根据类型去全局加载器类中查找,找不到报错,找到之后继续后面逻辑,可以根据我的图去细看
自定义全局加载器converterLoader
@Configuration
public class CustomerDefaultConverterLoader {
//存放写时用到的converter
private static final String ALL_CONVERTER = "allConverter";
//存放所有的converter
private static final String WRITE_CONVERTER = "defaultWriteConverter";
@Bean
public DefaultConverterLoader init() throws IllegalAccessException {
DefaultConverterLoader converters = new DefaultConverterLoader();
Field[] fields = converters.getClass().getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
if (field.getType() == Map.class) {
Map<String, Converter> oldMap = (Map<String, Converter>) field.get(converters);
//兼容高版本(2.2.0+)通过静态代码块初始化 复用旧代码 节省空间
if (oldMap != null && !oldMap.isEmpty()) {
if (WRITE_CONVERTER.equalsIgnoreCase(field.getName())) {
putWriteConverter(oldMap, new LocalDateTimeConverter());
} else if (ALL_CONVERTER.equalsIgnoreCase(field.getName())) {
putAllConverter(oldMap, new LocalDateTimeConverter());
}
field.set(converters, oldMap);
} else {
setConverter(converters, field);
}
}
}
return converters;
}
private void setConverter(DefaultConverterLoader converters, Field field) throws IllegalAccessException {
if (WRITE_CONVERTER.equalsIgnoreCase(field.getName())) {
Map<String, Converter> map = new HashMap<>(32);
//我的LocalDateTimeConverter
putWriteConverter(map, new LocalDateTimeConverter());
//以下jar包自带的Converter
putWriteConverter(map, new BigDecimalNumberConverter());
putWriteConverter(map, new BooleanBooleanConverter());
putWriteConverter(map, new ByteNumberConverter());
putWriteConverter(map, new DateStringConverter());
putWriteConverter(map, new DoubleNumberConverter());
putWriteConverter(map, new FloatNumberConverter());
putWriteConverter(map, new IntegerNumberConverter());
putWriteConverter(map, new LongNumberConverter());
putWriteConverter(map, new ShortNumberConverter());
putWriteConverter(map, new StringStringConverter());
putWriteConverter(map, new FileImageConverter());
putWriteConverter(map, new InputStreamImageConverter());
putWriteConverter(map, new ByteArrayImageConverter());
putWriteConverter(map, new BoxingByteArrayImageConverter());
putWriteConverter(map, new UrlImageConverter());
field.set(converters, map);
} else if (ALL_CONVERTER.equalsIgnoreCase(field.getName())) {
Map<String, Converter> map = new HashMap<>(64);
//我的LocalDateTimeConverter
putAllConverter(map, new LocalDateTimeConverter());
//以下jar包自带的Converter
putAllConverter(map, new BigDecimalBooleanConverter());
putAllConverter(map, new BigDecimalNumberConverter());
putAllConverter(map, new BigDecimalStringConverter());
putAllConverter(map, new BooleanBooleanConverter());
putAllConverter(map, new BooleanNumberConverter());
putAllConverter(map, new BooleanStringConverter());
putAllConverter(map, new ByteBooleanConverter());
putAllConverter(map, new ByteNumberConverter());
putAllConverter(map, new ByteStringConverter());
putAllConverter(map, new DateNumberConverter());
putAllConverter(map, new DateStringConverter());
putAllConverter(map, new DoubleBooleanConverter());
putAllConverter(map, new DoubleNumberConverter());
putAllConverter(map, new DoubleStringConverter());
putAllConverter(map, new FloatBooleanConverter());
putAllConverter(map, new FloatNumberConverter());
putAllConverter(map, new FloatStringConverter());
putAllConverter(map, new IntegerBooleanConverter());
putAllConverter(map, new IntegerNumberConverter());
putAllConverter(map, new IntegerStringConverter());
putAllConverter(map, new LongBooleanConverter());
putAllConverter(map, new LongNumberConverter());
putAllConverter(map, new LongStringConverter());
putAllConverter(map, new ShortBooleanConverter());
putAllConverter(map, new ShortNumberConverter());
putAllConverter(map, new ShortStringConverter());
putAllConverter(map, new StringBooleanConverter());
putAllConverter(map, new StringNumberConverter());
putAllConverter(map, new StringStringConverter());
putAllConverter(map, new StringErrorConverter());
field.set(converters, map);
}
}
private void putWriteConverter(Map<String, Converter> map, Converter converter) {
map.put(ConverterKeyBuild.buildKey(converter.supportJavaTypeKey()), converter);
}
private void putAllConverter(Map<String, Converter> map, Converter converter) {
map.put(ConverterKeyBuild.buildKey(converter.supportJavaTypeKey(), converter.supportExcelTypeKey()), converter);
}
}
好了EasyExcel总结到此结束,都是一些实际工作中用到的,虽然不是很深入,但是希望能够在日常工作中给大家带来帮助!
加油!
更多推荐
已为社区贡献3条内容
所有评论(0)