若依框架Excel列表导出,字段根据字典值翻译解决办法

一、原框架自带翻译方式

@Excel(name = "是否可用", readConverterExp = "0=不可用,1=可用", sort = 13)
@ApiModelProperty(value = "是否可用")
private Integer isAvailable;
注:此方式弊端,导出excel后字段翻译值只能固定,不便于后期维护扩展。

二、利用自定义数据处理

  1. 在实体类用Excel注解handler属性指定自定义的数据处理器
@Excel(name = "禁配原因", handler = MyDataHandler.class, args = { "forbid_reason"},sort = 3)
@ApiModelProperty(value = "禁配原因:来自字典选择")
private String forbidReason;
注:参数数组中,传入所需要查询字典表对应的字典type。
  1. 编写数据处理器MyDataHandler继承ExcelHandlerAdapter,返回值为处理后的值。
public class MyDataHandler implements ExcelHandlerAdapter
{
    private RemoteSystemService remoteSystemService = SpringUtils.getBean(RemoteSystemService.class);
    Map<String, String> map = new HashMap<>();
    @Override
    public Object format(Object value, String[] args) {
        // value 为单元格数据值
        // args 为excel注解args参数组
        if(StringUtils.isNotNull(value)){
            String forbidReason = value.toString();
            R<List<SysDictData>> dictResult = remoteSystemService.getDictByType(args[0], SecurityConstants.INNER);
            if(dictResult.getCode() == Constants.SUCCESS && StringUtils.isNotNull(dictResult.getData())) {
                dictResult.getData().forEach(d -> {
                    map.put(d.getDictValue(),d.getDictLabel());
                });
            }
            return map.get(forbidReason);
        }else{
            return "";
        }

    }
}
注:此方式弊端,根据每一个需要字典翻译的字段,可能都需要单独写一套“自定义数据处理器”。

三、改造ExcelUtil工具类

实现原始固定值方式,和字典翻译方式共存

  1. 编写字典加载服务接口
/**
 * 字典加载服务接口
 * @author Mr.Gao
 */
public interface DataDictLoadService {

    Map<String, String> loadDict(String key);
}
  1. 实现“字典加载服务接口”——根据某字典类型值,通过fegin查出此类型的所有字典数据,转为map
/**
 * @program: YQN_Base_Demo
 * @description: 获取字典map
        根据某字典类型值,通过fegin查出此类型的所有字典数据,转为map
 * @author: Mr.Gao
 * @create: 2022-02-16 13:28
 **/
@Service
public class DataDictLoadServiceImpl implements DataDictLoadService {

    @Autowired
    private RemoteSystemService remoteSystemService;

    @Override
    public Map<String, String> loadDict(String key) {
        Map<String, String> map = new HashMap<>();
        R<List<SysDictData>> dictResult = remoteSystemService.getDictByType(key, SecurityConstants.INNER);
        if(dictResult.getCode() == Constants.SUCCESS && StringUtils.isNotNull(dictResult.getData())) {
            dictResult.getData().forEach(d -> {
                map.put(d.getDictValue(),d.getDictLabel());
            });
        }
        return map;
    }
}
  1. 在ExcelUtil工具类加入属性
private DataDictLoadService dictLoadService;
//字典map
public Map<String, Map<String, String>> keyValueDict;
  1. ExcelUtil的构造方法中,注入DataDictLoadService的Bean
public ExcelUtil(Class<T> clazz) {
    this.clazz = clazz;
    this.dictLoadService = SpringUtils.getBean(DataDictLoadService.class);
}
  1. 将excel导出的实体类需要翻译的字段@Excel注解中readConverterExp属性值,改为英文#号拼接字典类型
@Excel(name = "禁配原因", readConverterExp = "#forbid_reason", sort = 3)
@ApiModelProperty(value = "禁配原因:来自字典选择")
private String forbidReason;
  1. ExcelUtil工具类加入createKeyValueDict()方法
    说明:此方法需要在init()中调用,生成excel时,获取此列@Excel注解readConverterExp属性值,是否以英文#号开头,若是则查出此类型字典map,存入初始化的map中。
public void createKeyValueDict(){
     keyValueDict = new HashMap<>(8);
     List<Object[]> fields = this.getFields();
     for (Object[] objects : fields) {
         Excel attr = (Excel) objects[1];
         String converterExp = attr.readConverterExp();
         if(converterExp.startsWith("#")){
             String key = converterExp.substring(1);
             keyValueDict.put(key, this.dictLoadService.loadDict(key));
         }
     }
}
  1. 在ExcelUtil初始化方法中调用createKeyValueDict()方法
public void init(List<T> list, String sheetName, String title, Type type) {
     if (list == null) {
         list = new ArrayList<T>();
     }
     this.list = list;
     this.sheetName = sheetName;
     this.type = type;
     this.title = title;
     createExcelField();
     createWorkbook();
     createTitle();
     createKeyValueDict();
}
  1. 优化解析导出值convertByExp()方法
/**
     * 解析导出值 0=男,1=女,2=未知
     *
     * @param propertyValue 参数值
     * @param converterExp  翻译注解
     * @param separator     分隔符
     * @return 解析后值
     */
    public String convertByExp(String propertyValue, String converterExp, String separator) {
        //判断是否以英文#号开头
        if(converterExp.startsWith("#")){
            //拆分字符串,取除去#号后的字典类型字符串
            String key = converterExp.substring(1);
            //拿到此字典类型的map
            Map<String, String> dict = this.keyValueDict.get(key);
            if(Objects.isNull(dict)){
                throw new ServiceException("获取"+key+"字典失败");
            }
            //根据当前字段值作为key获取字典map中value值
            String value = dict.get(propertyValue);
            if(StringUtils.isNotEmpty(value)){
                //不为空则翻译
                return value;
            }else{
                //为空则未进行翻译
                return propertyValue;
            }

        }
        
        //下方为原生方式实现方法,也就是未加#号形式

        StringBuilder propertyString = new StringBuilder();
        String[] convertSource = converterExp.split(",");
        for (String item : convertSource) {
            String[] itemArray = item.split("=");
            if (StringUtils.containsAny(separator, propertyValue)) {
                for (String value : propertyValue.split(separator)) {
                    if (itemArray[0].equals(value)) {
                        propertyString.append(itemArray[1] + separator);
                        break;
                    }
                }
            } else {
                if (itemArray[0].equals(propertyValue)) {
                    return itemArray[1];
                }
            }
        }
        return StringUtils.stripEnd(propertyString.toString(), separator);
    }
  • 1
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值