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总结到此结束,都是一些实际工作中用到的,虽然不是很深入,但是希望能够在日常工作中给大家带来帮助!

加油!

  • 31
    点赞
  • 64
    收藏
    觉得还不错? 一键收藏
  • 11
    评论
EasyExcel自定义Converter是指在使用EasyExcel进行Excel读写操作时,可以自定义转换来处理一些不支持的数据类型。通过自定义转换,我们可以将不支持的数据类型转换为EasyExcel支持的数据类型,以便正确地进行读写操作。 在SpringBoot中使用EasyExcel时,可以通过编写自定义转换来处理部分数据类型在导出时EasyExcel不支持的情况。首先,需要创建一个实现了Converter接口的转换类,比如CharConverter。在CharConverter中,我们需要实现supportJavaTypeKey方法,返回需要支持的数据类型,这里是Character类型。然后,我们需要实现convertToExcelData方法,对Character类型的数据进行自定义处理,比如将其转换为String类型。最后,将CharConverter注入为一个Spring组件。 在写操作时,需要将自定义的转换注册到EasyExcel中。可以通过调用registerConverter方法,并将自定义转换作为参数传入来实现。例如,在写学生信息到Excel的方法中,可以通过registerConverter(new CharConverter())将CharConverter注册到EasyExcel中。 需要注意的是,在不同的模块中,注册自定义转换的方式可能会有所不同。在某些模块中,可能需要使用build方法来创建WriteSheet对象,并在创建过程中注册转换。例如,在创建WriteSheet对象时,可以通过registerConverter方法将自定义转换注册到EasyExcel中。 通过自定义转换,我们可以灵活地处理EasyExcel不支持的数据类型,确保数据的正确读写。 #### 引用[.reference_title] - *1* *2* [EasyExcel 自定义类型转换](https://blog.csdn.net/weixin_45535519/article/details/130291453)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [15.EasyExcel自定义Convert遇到大坑!!!](https://blog.csdn.net/qq_37992410/article/details/126170990)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值