一、原框架自带翻译方式
@Excel(name = "是否可用", readConverterExp = "0=不可用,1=可用", sort = 13)
@ApiModelProperty(value = "是否可用")
private Integer isAvailable;
注:此方式弊端,导出excel后字段翻译值只能固定,不便于后期维护扩展。
二、利用自定义数据处理
- 在实体类用Excel注解handler属性指定自定义的数据处理器
@Excel(name = "禁配原因", handler = MyDataHandler.class, args = { "forbid_reason"},sort = 3)
@ApiModelProperty(value = "禁配原因:来自字典选择")
private String forbidReason;
注:参数数组中,传入所需要查询字典表对应的字典type。
- 编写数据处理器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) {
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工具类
实现原始固定值方式,和字典翻译方式共存
- 编写字典加载服务接口
public interface DataDictLoadService {
Map<String, String> loadDict(String key);
}
- 实现“字典加载服务接口”——根据某字典类型值,通过fegin查出此类型的所有字典数据,转为map
@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;
}
}
- 在ExcelUtil工具类加入属性
private DataDictLoadService dictLoadService;
public Map<String, Map<String, String>> keyValueDict;
- ExcelUtil的构造方法中,注入DataDictLoadService的Bean
public ExcelUtil(Class<T> clazz) {
this.clazz = clazz;
this.dictLoadService = SpringUtils.getBean(DataDictLoadService.class);
}
- 将excel导出的实体类需要翻译的字段@Excel注解中readConverterExp属性值,改为英文#号拼接字典类型
@Excel(name = "禁配原因", readConverterExp = "#forbid_reason", sort = 3)
@ApiModelProperty(value = "禁配原因:来自字典选择")
private String forbidReason;
- 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));
}
}
}
- 在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();
}
- 优化解析导出值convertByExp()方法
public String convertByExp(String propertyValue, String converterExp, String separator) {
if(converterExp.startsWith("#")){
String key = converterExp.substring(1);
Map<String, String> dict = this.keyValueDict.get(key);
if(Objects.isNull(dict)){
throw new ServiceException("获取"+key+"字典失败");
}
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);
}