实现 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;
	
相关推荐
栗豆包9 分钟前
w118共享汽车管理系统
java·spring boot·后端·spring·tomcat·maven
lly20240615 分钟前
Highcharts 饼图:数据可视化利器
开发语言
夜半被帅醒15 分钟前
MySQL 数据库优化详解【Java数据库调优】
java·数据库·mysql
lw向北.21 分钟前
Qt For Android之环境搭建(Qt 5.12.11 Qt下载SDK的处理方案)
android·开发语言·qt
万亿少女的梦16821 分钟前
基于Spring Boot的网络购物商城的设计与实现
java·spring boot·后端
不爱学习的啊Biao29 分钟前
【13】MySQL如何选择合适的索引?
android·数据库·mysql
破 风39 分钟前
SpringBoot 集成 MongoDB
数据库·mongodb
IT女孩儿42 分钟前
JavaScript--WebAPI查缺补漏(二)
开发语言·前端·javascript·html·ecmascript
m0_7482389243 分钟前
webgis入门实战案例——智慧校园
开发语言·ios·swift
Rverdoser1 小时前
MySQL-MVCC(多版本并发控制)
数据库·mysql