实现 easyExcel 导入导出自定义字典转换器

一、easyExcel 字典转换器 Converter

easyExcel 导入导出自定义字典转换器,包括导入字典转换以及导出字典转换。适配多个逗号分隔的字典值转换。

1、excel 导入字典转换注解

java 复制代码
import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * excel导入字典转换注解
 * <p>
 * 将excel导入的字典label自动转换为字典code
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@JacksonAnnotationsInside
@JsonSerialize(using = DictItemSerialize.class)
public @interface ExcelDictItemLabel {

	/**
	 * 字典type
	 */
	String type();

}

2、excel 导出字典转换注解

java 复制代码
import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * excel导出字典转换注解
 * <p>
 * 将excel导出的字典code自动转换为字典label
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@JacksonAnnotationsInside
@JsonSerialize(using = DictItemSerialize.class)
public @interface ExcelDictItem {

	/**
	 * 字典type
	 */
	String type();

}

3、自定义 excel 转换器

java 复制代码
import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.GlobalConfiguration;
import com.alibaba.excel.metadata.property.ExcelContentProperty;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.whitemeen.magic.common.core.constant.CacheConstants;
import com.whitemeen.magic.common.core.constant.SecurityConstants;
import com.whitemeen.magic.common.core.util.R;
import com.whitemeen.magic.common.core.util.SpringContextHolder;
import com.whitemeen.magic.upms.modules.admin.api.entity.SysDictItem;
import com.whitemeen.magic.upms.modules.admin.api.feign.RemoteDictService;
import com.whitemeen.magic.upms.modules.admin.config.ExcelDictItem;
import com.whitemeen.magic.upms.modules.admin.config.ExcelDictItemLabel;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;

import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * Excel Converter字典转换器
 */
public class ExcelDictConverter implements Converter<String> {

	public ExcelDictConverter() {
	}

	@Override
	public Class supportJavaTypeKey() {
		return null;
	}

	@Override
	public CellDataTypeEnum supportExcelTypeKey() {
		return null;
	}

	/**
	 * 将excel单元格数据转换成对象属性值(适配多个逗号分隔的字典值)
	 *
	 * @param cellData             单元格的数据
	 * @param excelContentProperty excel每一行的数据内容
	 * @param globalConfiguration  global全局配置
	 * @return 转换后的对象属性值
	 * @throws Exception 异常
	 */
	@Override
	public String convertToJavaData(CellData cellData, ExcelContentProperty excelContentProperty, GlobalConfiguration globalConfiguration) throws Exception {
		// 获取字典类型
		Field field = excelContentProperty.getField();
		ExcelDictItemLabel excel = field.getAnnotation(ExcelDictItemLabel.class);
		String dictType = excel.type();

		// 为空返回
		String dictLabel = cellData.getStringValue();
		if (StrUtil.isBlank(dictLabel)) {
			return dictLabel;
		}

		// 查询字典
		CacheManager cacheManager = SpringContextHolder.getBean(CacheManager.class);
		Cache dictCache = cacheManager.getCache(CacheConstants.DICT_DETAILS);
		R<List<SysDictItem>> dictItemListR = dictCache.get(dictType, R.class);

		if (dictItemListR == null) {
			RemoteDictService dictService = SpringContextHolder.getBean(RemoteDictService.class);
			dictItemListR = dictService.customize(dictType, SecurityConstants.FROM_IN);
		}
		if (dictItemListR == null || CollectionUtils.isEmpty(dictItemListR.getData())) {
			return dictLabel;
		}

		// 将字典项根据label分组
		Map<String, SysDictItem> dictItemLabelMap = dictItemListR.getData()
				.stream().collect(Collectors.toMap(SysDictItem::getLabel, Function.identity(), (v1, v2) -> v2));

		// 存在多个字典项值
		List<String> dictLabelList = Arrays.stream(dictLabel.split(",")).collect(Collectors.toList());
		StringBuilder dictValues = new StringBuilder();

		// 字典转换拼接
		for (String sourcesDictLabel : dictLabelList) {
			SysDictItem sysDictItem = dictItemLabelMap.get(sourcesDictLabel);
			if (sysDictItem == null) {
				continue;
			}

			if (StrUtil.isBlank(dictValues)) {
				dictValues.append(sysDictItem.getItemValue());
			} else {
				dictValues.append(",").append(sysDictItem.getItemValue());
			}
		}

		return String.valueOf(dictValues);
	}

	
//	/**
//	 * 将excel单元格数据转换成对象属性值(仅适配单个字典值)
//	 *
//	 * @param cellData             单元格的数据
//	 * @param excelContentProperty excel每一行的数据内容
//	 * @param globalConfiguration  global全局配置
//	 * @return 转换后的对象属性值
//	 * @throws Exception 异常
//	 */
//	@Override
//	public String convertToJavaData(CellData cellData, ExcelContentProperty excelContentProperty, GlobalConfiguration globalConfiguration) throws Exception {
//		// 获取字典类型
//		Field field = excelContentProperty.getField();
//		ExcelDictItemLabel excel = field.getAnnotation(ExcelDictItemLabel.class);
//		String dictType = excel.type();
//
//		String dictLabel = cellData.getStringValue();
//		if (StrUtil.isBlank(dictLabel)) {
//			return dictLabel;
//		}
//		// 查询字典
//		RemoteDictService remoteDictService = SpringContextHolder.getBean(RemoteDictService.class);
//		R<List<SysDictItem>> dictItemsR = remoteDictService.getDictByType(dictType);
//		if (CollectionUtil.isEmpty(dictItemsR.getData())) {
//			return dictLabel;
//		}
//		// 进行字典翻译
//		String javaData = dictLabel;
//		List<SysDictItem> dictItems = dictItemsR.getData();
//		for (SysDictItem dictItem : dictItems) {
//			if (StrUtil.equals(dictLabel, dictItem.getLabel())) {
//				javaData = dictItem.getItemValue();
//				break;
//			}
//		}
//		return javaData;
//	}

	/**
	 * 将对象属性值转换成excel单元格数据(适配多个逗号分隔的字典值)
	 *
	 * @param dictValue            对象的属性值
	 * @param excelContentProperty excel每一行的数据内容
	 * @param globalConfiguration  global全局配置
	 * @return 转换后的对象属性值
	 * @throws Exception 异常
	 */
	@Override
	public CellData convertToExcelData(String dictValue, ExcelContentProperty excelContentProperty, GlobalConfiguration globalConfiguration) throws Exception {
		// 获取字典类型
		Field field = excelContentProperty.getField();
		ExcelDictItem excel = field.getAnnotation(ExcelDictItem.class);
		String dictType = excel.type();

		// 为空返回
		if (StrUtil.isBlank(dictValue)) {
			return new CellData(dictValue);
		}

		// 查询字典
		CacheManager cacheManager = SpringContextHolder.getBean(CacheManager.class);
		Cache dictCache = cacheManager.getCache(CacheConstants.DICT_DETAILS);
		R<List<SysDictItem>> dictItemListR = dictCache.get(dictType, R.class);

		if (dictItemListR == null) {
			RemoteDictService dictService = SpringContextHolder.getBean(RemoteDictService.class);
			dictItemListR = dictService.customize(dictType, SecurityConstants.FROM_IN);
		}
		if (dictItemListR == null || CollectionUtils.isEmpty(dictItemListR.getData())) {
			return new CellData(dictValue);
		}

		// 将字典项根据value分组
		Map<String, SysDictItem> dictItemValueMap = dictItemListR.getData()
				.stream().collect(Collectors.toMap(SysDictItem::getItemValue, Function.identity(), (v1, v2) -> v2));

		// 存在多个字典项值
		List<String> dictValueList = Arrays.stream(dictValue.split(",")).collect(Collectors.toList());
		StringBuilder dictLabels = new StringBuilder();

		// 字典转换拼接
		for (String sourcesDictLabel : dictValueList) {
			SysDictItem sysDictItem = dictItemValueMap.get(sourcesDictLabel);
			if (sysDictItem == null) {
				continue;
			}

			if (StrUtil.isBlank(dictLabels)) {
				dictLabels.append(sysDictItem.getLabel());
			} else {
				dictLabels.append(",").append(sysDictItem.getLabel());
			}
		}

		if(StrUtil.isBlank(String.valueOf(dictLabels))){
			return new CellData(dictValue);
		}
		return new CellData(String.valueOf(dictLabels));
	}
	
//	/**
//	 * 将对象属性值转换成excel单元格数据(仅适配单个字典值)
//	 *
//	 * @param dictValue            对象的属性值
//	 * @param excelContentProperty excel每一行的数据内容
//	 * @param globalConfiguration  global全局配置
//	 * @return 转换后的对象属性值
//	 * @throws Exception 异常
//	 */
//	@Override
//	public CellData convertToExcelData(String dictValue, ExcelContentProperty excelContentProperty, GlobalConfiguration globalConfiguration) throws Exception {
//		// 获取字典类型
//		Field field = excelContentProperty.getField();
//		String fieldName = field.getName();
//		DictItem excel = field.getAnnotation(DictItem.class);
//		String dictType = excel.type();
//		// 查询字典
//		RemoteDictService remoteDictService = SpringContextHolder.getBean(RemoteDictService.class);
//		R<List<SysDictItem>> dictItemsR = remoteDictService.getDictByType(dictType);
//		if (CollectionUtil.isEmpty(dictItemsR.getData())) {
//			return new CellData(dictValue);
//		}
//		// 进行字典翻译
//		String excelData = dictValue;
//		List<SysDictItem> dictItems = dictItemsR.getData();
//		for (SysDictItem dictItem : dictItems) {
//			if (StrUtil.equals(dictValue, dictItem.getItemValue())) {
//				excelData = dictItem.getLabel();
//				break;
//			}
//		}
//		return new CellData(excelData);
//	}

}

4、使用 excel 字典转换注解

java 复制代码
	/**
	 * 性别label(用于接收与展现真实的excel内容)
	 */
	@ExcelProperty(value = "性别", converter = ExcelDictConverter.class)
	@ExcelDictItemLabel(type = "gender")
	private String genderLabel;

	/**
	 * 性别code(用来承载java对象属性值)
	 */
	@ExcelIgnore
	@ExcelDictItem(type = "gender")
	private String gender;
	
相关推荐
恒辉信达6 分钟前
hhdb数据库介绍(8-4)
服务器·数据库·mysql
blammmp12 分钟前
Java:数据结构-枚举
java·开发语言·数据结构
何曾参静谧25 分钟前
「C/C++」C/C++ 指针篇 之 指针运算
c语言·开发语言·c++
暗黑起源喵31 分钟前
设计模式-工厂设计模式
java·开发语言·设计模式
WaaTong35 分钟前
Java反射
java·开发语言·反射
Troc_wangpeng37 分钟前
R language 关于二维平面直角坐标系的制作
开发语言·机器学习
努力的家伙是不讨厌的38 分钟前
解析json导出csv或者直接入库
开发语言·python·json
Envyᥫᩣ1 小时前
C#语言:从入门到精通
开发语言·c#
齐 飞1 小时前
MongoDB笔记01-概念与安装
前端·数据库·笔记·后端·mongodb
云空1 小时前
《Python 与 SQLite:强大的数据库组合》
数据库·python·sqlite