mirror of
https://gitee.com/y_project/RuoYi-Cloud.git
synced 2026-10-19 16:16:01 +00:00
Excel添加字典数据转换支持
This commit is contained in:
+10
@@ -33,6 +33,11 @@ public @interface Excel
|
||||
*/
|
||||
public String dateFormat() default "";
|
||||
|
||||
/**
|
||||
* 如果是字典类型,请设置字典的type值 (如: sys_user_sex)
|
||||
*/
|
||||
public String dictType() default "";
|
||||
|
||||
/**
|
||||
* 读取内容转表达式 (如: 0=男,1=女,2=未知)
|
||||
*/
|
||||
@@ -89,6 +94,11 @@ public @interface Excel
|
||||
*/
|
||||
public String[] combo() default {};
|
||||
|
||||
/**
|
||||
* 是否从字典读数据到combo,默认不读取,如读取需要设置dictType注解.
|
||||
*/
|
||||
public boolean comboReadDict() default false;
|
||||
|
||||
/**
|
||||
* 是否需要纵向合并单元格,应对需求:含有list集合单元格)
|
||||
*/
|
||||
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
package com.ruoyi.common.core.utils.poi;
|
||||
|
||||
/**
|
||||
* Excel字典数据转换
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public interface ExcelDictDataConverter
|
||||
{
|
||||
/**
|
||||
* 根据字典类型和字典键值获取字典标签
|
||||
*
|
||||
* @param dictType 字典类型
|
||||
* @param dictValue 字典键值
|
||||
* @return 字典标签
|
||||
*/
|
||||
String getDictLabel(String dictType, String dictValue, String separator);
|
||||
|
||||
/**
|
||||
* 根据字典类型和字典标签获取字典键值
|
||||
*
|
||||
* @param dictType 字典类型
|
||||
* @param dictLabel 字典标签
|
||||
* @return 字典键值
|
||||
*/
|
||||
String getDictValue(String dictType, String dictLabel, String separator);
|
||||
|
||||
/**
|
||||
* 根据字典类型获取字典标签列表
|
||||
*
|
||||
* @param dictType 字典类型
|
||||
* @return 字典标签列表
|
||||
*/
|
||||
String getDictLabels(String dictType);
|
||||
}
|
||||
+91
-6
@@ -94,6 +94,11 @@ public class ExcelUtil<T>
|
||||
|
||||
public static final String[] FORMULA_STR = { "=", "-", "+", "@" };
|
||||
|
||||
/**
|
||||
* 用于dictType属性数据存储,避免重复查缓存
|
||||
*/
|
||||
public Map<String, String> sysDictMap = new HashMap<String, String>();
|
||||
|
||||
/**
|
||||
* 单元格样式缓存
|
||||
*/
|
||||
@@ -199,6 +204,11 @@ public class ExcelUtil<T>
|
||||
*/
|
||||
private ExcelImageHandler imageHandler;
|
||||
|
||||
/**
|
||||
* 字典数据转换器
|
||||
*/
|
||||
private ExcelDictDataConverter dictDataConverter;
|
||||
|
||||
public ExcelUtil(Class<T> clazz)
|
||||
{
|
||||
this.clazz = clazz;
|
||||
@@ -224,6 +234,26 @@ public class ExcelUtil<T>
|
||||
return imageHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取字典数据转换器
|
||||
*
|
||||
* @return 字典数据转换器
|
||||
*/
|
||||
private ExcelDictDataConverter getDictDataConverter()
|
||||
{
|
||||
if (dictDataConverter == null)
|
||||
{
|
||||
try
|
||||
{
|
||||
dictDataConverter = SpringUtils.getBean(ExcelDictDataConverter.class);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
}
|
||||
}
|
||||
return dictDataConverter;
|
||||
}
|
||||
|
||||
/**
|
||||
* 仅在Excel中显示列属性
|
||||
*
|
||||
@@ -510,6 +540,15 @@ public class ExcelUtil<T>
|
||||
{
|
||||
val = reverseByExp(Convert.toStr(val), attr.readConverterExp(), attr.separator());
|
||||
}
|
||||
else if (StringUtils.isNotEmpty(attr.dictType()))
|
||||
{
|
||||
if (!sysDictMap.containsKey(attr.dictType() + val))
|
||||
{
|
||||
String dictValue = reverseDictByExp(Convert.toStr(val), attr.dictType(), attr.separator());
|
||||
sysDictMap.put(attr.dictType() + val, dictValue);
|
||||
}
|
||||
val = sysDictMap.get(attr.dictType() + val);
|
||||
}
|
||||
else if (!attr.handler().equals(ExcelHandlerAdapter.class))
|
||||
{
|
||||
val = dataFormatHandlerAdapter(val, attr, null);
|
||||
@@ -1098,13 +1137,12 @@ public class ExcelUtil<T>
|
||||
{
|
||||
return defaultVal;
|
||||
}
|
||||
ExcelImageHandler imageHandler = getImageHandler();
|
||||
StringBuilder propertyString = new StringBuilder();
|
||||
for (PictureData picture : images)
|
||||
{
|
||||
byte[] data = picture.getData();
|
||||
String extension = FileTypeUtils.getFileExtendName(data).toLowerCase();
|
||||
propertyString.append(imageHandler.upload(data, extension)).append(SEPARATOR);
|
||||
propertyString.append(getImageHandler().upload(data, extension)).append(SEPARATOR);
|
||||
}
|
||||
return StringUtils.stripEnd(propertyString.toString(), SEPARATOR);
|
||||
}
|
||||
@@ -1181,17 +1219,28 @@ public class ExcelUtil<T>
|
||||
// 设置列宽
|
||||
sheet.setColumnWidth(column, (int) ((attr.width() + 0.72) * 256));
|
||||
}
|
||||
if (StringUtils.isNotEmpty(attr.prompt()) || attr.combo().length > 0)
|
||||
if (StringUtils.isNotEmpty(attr.prompt()) || attr.combo().length > 0 || attr.comboReadDict())
|
||||
{
|
||||
if (attr.combo().length > 15 || StringUtils.join(attr.combo()).length() > 255)
|
||||
String[] comboArray = attr.combo();
|
||||
if (attr.comboReadDict())
|
||||
{
|
||||
if (!sysDictMap.containsKey("combo_" + attr.dictType()))
|
||||
{
|
||||
String labels = getDictDataConverter().getDictLabels(attr.dictType());
|
||||
sysDictMap.put("combo_" + attr.dictType(), labels);
|
||||
}
|
||||
String val = sysDictMap.get("combo_" + attr.dictType());
|
||||
comboArray = StringUtils.split(val, SEPARATOR);
|
||||
}
|
||||
if (comboArray.length > 15 || StringUtils.join(comboArray).length() > 255)
|
||||
{
|
||||
// 如果下拉数大于15或字符串长度大于255,则使用一个新sheet存储,避免生成的模板下拉值获取不到
|
||||
setXSSFValidationWithHidden(sheet, attr.combo(), attr.prompt(), 1, 100, column, column);
|
||||
setXSSFValidationWithHidden(sheet, comboArray, attr.prompt(), 1, 100, column, column);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 提示信息或只能选择不能输入的列内容.
|
||||
setPromptOrValidation(sheet, attr.combo(), attr.prompt(), 1, 100, column, column);
|
||||
setPromptOrValidation(sheet, comboArray, attr.prompt(), 1, 100, column, column);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1226,6 +1275,7 @@ public class ExcelUtil<T>
|
||||
String dateFormat = attr.dateFormat();
|
||||
String readConverterExp = attr.readConverterExp();
|
||||
String separator = attr.separator();
|
||||
String dictType = attr.dictType();
|
||||
if (StringUtils.isNotEmpty(dateFormat) && StringUtils.isNotNull(value))
|
||||
{
|
||||
cell.setCellStyle(createCellStyle(cell.getCellStyle(), dateFormat));
|
||||
@@ -1235,6 +1285,15 @@ public class ExcelUtil<T>
|
||||
{
|
||||
cell.setCellValue(convertByExp(Convert.toStr(value), readConverterExp, separator));
|
||||
}
|
||||
else if (StringUtils.isNotEmpty(dictType) && StringUtils.isNotNull(value))
|
||||
{
|
||||
if (!sysDictMap.containsKey(dictType + value))
|
||||
{
|
||||
String lable = convertDictByExp(Convert.toStr(value), dictType, separator);
|
||||
sysDictMap.put(dictType + value, lable);
|
||||
}
|
||||
cell.setCellValue(sysDictMap.get(dictType + value));
|
||||
}
|
||||
else if (value instanceof BigDecimal && -1 != attr.scale())
|
||||
{
|
||||
cell.setCellValue((((BigDecimal) value).setScale(attr.scale(), attr.roundingMode())).doubleValue());
|
||||
@@ -1461,6 +1520,32 @@ public class ExcelUtil<T>
|
||||
return StringUtils.stripEnd(propertyString.toString(), separator);
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析字典值
|
||||
*
|
||||
* @param dictValue 字典值
|
||||
* @param dictType 字典类型
|
||||
* @param separator 分隔符
|
||||
* @return 字典标签
|
||||
*/
|
||||
public String convertDictByExp(String dictValue, String dictType, String separator)
|
||||
{
|
||||
return getDictDataConverter().getDictLabel(dictType, dictValue, separator);
|
||||
}
|
||||
|
||||
/**
|
||||
* 反向解析值字典值
|
||||
*
|
||||
* @param dictLabel 字典标签
|
||||
* @param dictType 字典类型
|
||||
* @param separator 分隔符
|
||||
* @return 字典值
|
||||
*/
|
||||
public String reverseDictByExp(String dictLabel, String dictType, String separator)
|
||||
{
|
||||
return getDictDataConverter().getDictValue(dictType, dictLabel, separator);
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据处理器
|
||||
*
|
||||
|
||||
+64
@@ -1,7 +1,9 @@
|
||||
package com.ruoyi.common.security.utils;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import com.alibaba.fastjson2.JSONArray;
|
||||
import com.ruoyi.common.core.constant.CacheConstants;
|
||||
import com.ruoyi.common.core.utils.SpringUtils;
|
||||
@@ -16,6 +18,68 @@ import com.ruoyi.system.api.domain.SysDictData;
|
||||
*/
|
||||
public class DictUtils
|
||||
{
|
||||
/**
|
||||
* 根据字典类型和字典值获取字典标签
|
||||
*
|
||||
* @param dictType 字典类型
|
||||
* @param dictValue 字典值
|
||||
* @param separator 分隔符
|
||||
* @return 字典标签
|
||||
*/
|
||||
public static String getDictLabel(String dictType, String dictValue, String separator)
|
||||
{
|
||||
List<SysDictData> datas = DictUtils.getDictCache(dictType);
|
||||
if (StringUtils.isNull(datas) || StringUtils.isEmpty(dictValue))
|
||||
{
|
||||
return StringUtils.EMPTY;
|
||||
}
|
||||
Map<String, String> dictMap = datas.stream().collect(HashMap::new, (map, dict) -> map.put(dict.getDictValue(), dict.getDictLabel()), Map::putAll);
|
||||
if (!StringUtils.contains(dictValue, separator))
|
||||
{
|
||||
return dictMap.getOrDefault(dictValue, StringUtils.EMPTY);
|
||||
}
|
||||
StringBuilder labelBuilder = new StringBuilder();
|
||||
for (String seperatedValue : dictValue.split(separator))
|
||||
{
|
||||
if (dictMap.containsKey(seperatedValue))
|
||||
{
|
||||
labelBuilder.append(dictMap.get(seperatedValue)).append(separator);
|
||||
}
|
||||
}
|
||||
return StringUtils.removeEnd(labelBuilder.toString(), separator);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据字典类型和字典标签获取字典值
|
||||
*
|
||||
* @param dictType 字典类型
|
||||
* @param dictLabel 字典标签
|
||||
* @param separator 分隔符
|
||||
* @return 字典值
|
||||
*/
|
||||
public static String getDictValue(String dictType, String dictLabel, String separator)
|
||||
{
|
||||
List<SysDictData> datas = DictUtils.getDictCache(dictType);
|
||||
if (StringUtils.isNull(datas) || StringUtils.isEmpty(dictLabel))
|
||||
{
|
||||
return StringUtils.EMPTY;
|
||||
}
|
||||
Map<String, String> dictMap = datas.stream().collect(HashMap::new, (map, dict) -> map.put(dict.getDictLabel(), dict.getDictValue()), Map::putAll);
|
||||
if (!StringUtils.contains(dictLabel, separator))
|
||||
{
|
||||
return dictMap.getOrDefault(dictLabel, StringUtils.EMPTY);
|
||||
}
|
||||
StringBuilder valueBuilder = new StringBuilder();
|
||||
for (String seperatedValue : dictLabel.split(separator))
|
||||
{
|
||||
if (dictMap.containsKey(seperatedValue))
|
||||
{
|
||||
valueBuilder.append(dictMap.get(seperatedValue)).append(separator);
|
||||
}
|
||||
}
|
||||
return StringUtils.removeEnd(valueBuilder.toString(), separator);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置字典缓存
|
||||
*
|
||||
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
package com.ruoyi.common.security.utils.poi;
|
||||
|
||||
import java.util.List;
|
||||
import org.springframework.stereotype.Component;
|
||||
import com.ruoyi.common.core.utils.StringUtils;
|
||||
import com.ruoyi.common.core.utils.poi.ExcelDictDataConverter;
|
||||
import com.ruoyi.common.security.utils.DictUtils;
|
||||
import com.ruoyi.system.api.domain.SysDictData;
|
||||
|
||||
/**
|
||||
* 字典数据转换
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Component
|
||||
public class DictDataConverter implements ExcelDictDataConverter
|
||||
{
|
||||
/**
|
||||
* 分隔符
|
||||
*/
|
||||
public static final String SEPARATOR = ",";
|
||||
|
||||
/**
|
||||
* 根据字典类型和字典值获取字典标签
|
||||
*
|
||||
* @param dictType 字典类型
|
||||
* @param dictValue 字典值
|
||||
* @return 字典标签
|
||||
*/
|
||||
@Override
|
||||
public String getDictLabel(String dictType, String dictValue, String separator)
|
||||
{
|
||||
if (StringUtils.isEmpty(dictValue))
|
||||
{
|
||||
return StringUtils.EMPTY;
|
||||
}
|
||||
return DictUtils.getDictLabel(dictType, dictValue, separator);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据字典类型和字典标签获取字典值
|
||||
*
|
||||
* @param dictType 字典类型
|
||||
* @param dictLabel 字典标签
|
||||
* @return 字典值
|
||||
*/
|
||||
@Override
|
||||
public String getDictValue(String dictType, String dictLabel, String separator)
|
||||
{
|
||||
if (StringUtils.isEmpty(dictLabel))
|
||||
{
|
||||
return StringUtils.EMPTY;
|
||||
}
|
||||
return DictUtils.getDictValue(dictType, dictLabel, separator);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据字典类型获取字典所有标签
|
||||
*
|
||||
* @param dictType 字典类型
|
||||
* @return 字典值
|
||||
*/
|
||||
@Override
|
||||
public String getDictLabels(String dictType)
|
||||
{
|
||||
StringBuilder propertyString = new StringBuilder();
|
||||
List<SysDictData> datas = DictUtils.getDictCache(dictType);
|
||||
if (StringUtils.isNull(datas))
|
||||
{
|
||||
return StringUtils.EMPTY;
|
||||
}
|
||||
for (SysDictData dict : datas)
|
||||
{
|
||||
propertyString.append(dict.getDictLabel()).append(SEPARATOR);
|
||||
}
|
||||
return StringUtils.stripEnd(propertyString.toString(), SEPARATOR);
|
||||
}
|
||||
}
|
||||
+1
@@ -3,3 +3,4 @@ com.ruoyi.common.security.service.TokenService
|
||||
com.ruoyi.common.security.aspect.PreAuthorizeAspect
|
||||
com.ruoyi.common.security.aspect.InnerAuthAspect
|
||||
com.ruoyi.common.security.handler.GlobalExceptionHandler
|
||||
com.ruoyi.common.security.utils.poi.DictDataConverter
|
||||
|
||||
Reference in New Issue
Block a user