mirror of
https://gitee.com/dromara/RuoYi-Vue-Plus.git
synced 2026-09-22 02:50:00 +08:00
feat(优化注解|反向解析失效):
1.去除DropDown注解,改为使用DictDataFormat注解 2.修复DictEnumFormat注解Excel转Java时解析失效的问题
This commit is contained in:
parent
09ca147ab2
commit
110df3a175
@ -1,21 +0,0 @@
|
|||||||
package com.ruoyi.common.annotation;
|
|
||||||
|
|
||||||
import java.lang.annotation.*;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Excel下拉注解
|
|
||||||
* <p>注解在实体类中的属性上,与@ExcelProperty同级</p>
|
|
||||||
*
|
|
||||||
* @author slYe
|
|
||||||
* @author Emil.Zhang
|
|
||||||
*/
|
|
||||||
@Documented
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
@Target({ElementType.FIELD})
|
|
||||||
public @interface DropDown {
|
|
||||||
/**
|
|
||||||
* 下拉框可选值,用于简单的指定可选值
|
|
||||||
* <p>例如: @DropDown({"选项1","选项2"})</p>
|
|
||||||
*/
|
|
||||||
String[] value();
|
|
||||||
}
|
|
||||||
@ -37,14 +37,34 @@ public class ExcelEnumConvert implements Converter<Object> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object convertToJavaData(ReadCellData<?> cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {
|
public Object convertToJavaData(ReadCellData<?> cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {
|
||||||
Object codeValue = cellData.getData();
|
cellData.checkEmpty();
|
||||||
|
// Excel中填入的是枚举中指定的描述
|
||||||
|
Object textValue = null;
|
||||||
|
switch (cellData.getType()) {
|
||||||
|
case STRING:
|
||||||
|
case DIRECT_STRING:
|
||||||
|
case RICH_TEXT_STRING:
|
||||||
|
textValue = cellData.getStringValue();
|
||||||
|
break;
|
||||||
|
case NUMBER:
|
||||||
|
textValue = cellData.getNumberValue();
|
||||||
|
break;
|
||||||
|
case BOOLEAN:
|
||||||
|
textValue = cellData.getBooleanValue();
|
||||||
|
break;
|
||||||
|
}
|
||||||
// 如果是空值
|
// 如果是空值
|
||||||
if (ObjectUtil.isNull(codeValue)) {
|
if (ObjectUtil.isNull(textValue)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
Map<Object, String> enumValueMap = beforeConvert(contentProperty);
|
Map<Object, String> enumCodeToTextMap = beforeConvert(contentProperty);
|
||||||
String textValue = enumValueMap.get(codeValue);
|
// 从Java输出至Excel是code转text
|
||||||
return Convert.convert(contentProperty.getField().getType(), textValue);
|
// 因此从Excel转Java应该将text与code对调
|
||||||
|
Map<Object, Object> enumTextToCodeMap = new HashMap<>();
|
||||||
|
enumCodeToTextMap.forEach((key, value) -> enumTextToCodeMap.put(value, key));
|
||||||
|
// 应该从text -> code中查找
|
||||||
|
Object codeValue = enumTextToCodeMap.get(textValue);
|
||||||
|
return Convert.convert(contentProperty.getField().getType(), codeValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@ -1,5 +1,9 @@
|
|||||||
package com.ruoyi.common.core.service;
|
package com.ruoyi.common.core.service;
|
||||||
|
|
||||||
|
import com.ruoyi.common.core.domain.entity.SysDictData;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 通用 字典服务
|
* 通用 字典服务
|
||||||
*
|
*
|
||||||
@ -54,4 +58,11 @@ public interface DictService {
|
|||||||
*/
|
*/
|
||||||
String getDictValue(String dictType, String dictLabel, String separator);
|
String getDictValue(String dictType, String dictLabel, String separator);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据字典类型查询字典数据
|
||||||
|
*
|
||||||
|
* @param dictType 字典类型
|
||||||
|
* @return 字典数据集合信息
|
||||||
|
*/
|
||||||
|
List<SysDictData> selectDictDataByType(String dictType);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -39,6 +39,10 @@ public class DropDownOptions {
|
|||||||
* <p>以每一个一级选项值为Key,每个一级选项对应的二级数据为Value</p>
|
* <p>以每一个一级选项值为Key,每个一级选项对应的二级数据为Value</p>
|
||||||
*/
|
*/
|
||||||
private Map<String, List<String>> nextOptions = new HashMap<>();
|
private Map<String, List<String>> nextOptions = new HashMap<>();
|
||||||
|
/**
|
||||||
|
* 分隔符
|
||||||
|
*/
|
||||||
|
private static final String DELIMITER = "_";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建只有一级的下拉选
|
* 创建只有一级的下拉选
|
||||||
@ -66,7 +70,7 @@ public class DropDownOptions {
|
|||||||
stringBuffer.append(StrUtil.trimToEmpty(var.toString()));
|
stringBuffer.append(StrUtil.trimToEmpty(var.toString()));
|
||||||
if (i < vars.length - 1) {
|
if (i < vars.length - 1) {
|
||||||
// 直至最后一个前,都以_作为切割线
|
// 直至最后一个前,都以_作为切割线
|
||||||
stringBuffer.append("_");
|
stringBuffer.append(DELIMITER);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (stringBuffer.toString().matches("^\\d_*$")) {
|
if (stringBuffer.toString().matches("^\\d_*$")) {
|
||||||
@ -74,4 +78,14 @@ public class DropDownOptions {
|
|||||||
}
|
}
|
||||||
return stringBuffer.toString();
|
return stringBuffer.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将处理后合理的可选值解析为原始的参数
|
||||||
|
*
|
||||||
|
* @param option 经过处理后的合理的可选项
|
||||||
|
* @return 原始的参数
|
||||||
|
*/
|
||||||
|
public static List<String> analyzeOptionValue(String option) {
|
||||||
|
return StrUtil.split(option, DELIMITER, true, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,12 +1,18 @@
|
|||||||
package com.ruoyi.common.excel;
|
package com.ruoyi.common.excel;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.EnumUtil;
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import com.alibaba.excel.annotation.ExcelProperty;
|
import com.alibaba.excel.annotation.ExcelProperty;
|
||||||
import com.alibaba.excel.write.handler.SheetWriteHandler;
|
import com.alibaba.excel.write.handler.SheetWriteHandler;
|
||||||
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
|
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
|
||||||
import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder;
|
import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder;
|
||||||
import com.ruoyi.common.annotation.DropDown;
|
import com.ruoyi.common.annotation.ExcelDictFormat;
|
||||||
|
import com.ruoyi.common.annotation.ExcelEnumFormat;
|
||||||
|
import com.ruoyi.common.core.domain.entity.SysDictData;
|
||||||
|
import com.ruoyi.common.core.service.DictService;
|
||||||
|
import com.ruoyi.common.exception.ServiceException;
|
||||||
|
import com.ruoyi.common.utils.spring.SpringUtils;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.poi.ss.usermodel.*;
|
import org.apache.poi.ss.usermodel.*;
|
||||||
import org.apache.poi.ss.util.CellRangeAddressList;
|
import org.apache.poi.ss.util.CellRangeAddressList;
|
||||||
@ -15,6 +21,7 @@ import org.apache.poi.xssf.usermodel.XSSFDataValidation;
|
|||||||
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <h1>Excel表格下拉选操作</h1>
|
* <h1>Excel表格下拉选操作</h1>
|
||||||
@ -52,11 +59,13 @@ public class ExcelDownHandler implements SheetWriteHandler {
|
|||||||
* 当前联动选择进度
|
* 当前联动选择进度
|
||||||
*/
|
*/
|
||||||
private int currentLinkedOptionsSheetIndex;
|
private int currentLinkedOptionsSheetIndex;
|
||||||
|
private final DictService dictService;
|
||||||
|
|
||||||
public ExcelDownHandler(List<DropDownOptions> options) {
|
public ExcelDownHandler(List<DropDownOptions> options) {
|
||||||
this.dropDownOptions = options;
|
this.dropDownOptions = options;
|
||||||
this.currentOptionsColumnIndex = 0;
|
this.currentOptionsColumnIndex = 0;
|
||||||
this.currentLinkedOptionsSheetIndex = 0;
|
this.currentLinkedOptionsSheetIndex = 0;
|
||||||
|
this.dictService = SpringUtils.getBean(DictService.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -77,18 +86,56 @@ public class ExcelDownHandler implements SheetWriteHandler {
|
|||||||
Workbook workbook = writeWorkbookHolder.getWorkbook();
|
Workbook workbook = writeWorkbookHolder.getWorkbook();
|
||||||
int length = fields.length;
|
int length = fields.length;
|
||||||
for (int i = 0; i < length; i++) {
|
for (int i = 0; i < length; i++) {
|
||||||
if (fields[i].isAnnotationPresent(DropDown.class)) {
|
// 循环实体中的每个属性
|
||||||
// 获取设定的下拉选
|
// 可选的下拉值
|
||||||
List<String> options = Arrays.asList(fields[i].getDeclaredAnnotation(DropDown.class).value());
|
List<String> options = new ArrayList<>();
|
||||||
|
if (fields[i].isAnnotationPresent(ExcelDictFormat.class)) {
|
||||||
|
// 如果指定了@ExcelDictFormat,则使用字典的逻辑
|
||||||
|
ExcelDictFormat thisFiledExcelDictFormat = fields[i].getDeclaredAnnotation(ExcelDictFormat.class);
|
||||||
|
String dictType = thisFiledExcelDictFormat.dictType();
|
||||||
|
String converterExp = thisFiledExcelDictFormat.readConverterExp();
|
||||||
|
if (StrUtil.isNotBlank(dictType)) {
|
||||||
|
// 如果传递了字典名,则依据字典建立下拉
|
||||||
|
options =
|
||||||
|
Optional.ofNullable(dictService.selectDictDataByType(dictType))
|
||||||
|
.orElseThrow(() -> new ServiceException(String.format("字典 %s 不存在", dictType)))
|
||||||
|
.stream()
|
||||||
|
.map(SysDictData::getDictLabel)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
} else if (StrUtil.isNotBlank(converterExp)) {
|
||||||
|
// 如果指定了确切的值,则直接解析确切的值
|
||||||
|
options = StrUtil.split(
|
||||||
|
converterExp,
|
||||||
|
thisFiledExcelDictFormat.separator(),
|
||||||
|
true,
|
||||||
|
true);
|
||||||
|
}
|
||||||
|
} else if (fields[i].isAnnotationPresent(ExcelEnumFormat.class)) {
|
||||||
|
// 否则如果指定了@ExcelEnumFormat,则使用枚举的逻辑
|
||||||
|
ExcelEnumFormat thisFiledExcelEnumFormat = fields[i].getDeclaredAnnotation(ExcelEnumFormat.class);
|
||||||
|
options =
|
||||||
|
EnumUtil
|
||||||
|
.getFieldValues(
|
||||||
|
thisFiledExcelEnumFormat.enumClass(),
|
||||||
|
thisFiledExcelEnumFormat.textField()
|
||||||
|
)
|
||||||
|
.stream()
|
||||||
|
.map(String::valueOf)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
if (ObjectUtil.isNotEmpty(options)) {
|
||||||
|
// 仅当下拉可选项不为空时执行
|
||||||
// 获取列下标,默认为当前循环次数
|
// 获取列下标,默认为当前循环次数
|
||||||
int index = i;
|
int index = i;
|
||||||
if (fields[i].isAnnotationPresent(ExcelProperty.class)) {
|
if (fields[i].isAnnotationPresent(ExcelProperty.class)) {
|
||||||
// 如果制定了列下标,以指定的为主
|
// 如果指定了列下标,以指定的为主
|
||||||
index = fields[i].getDeclaredAnnotation(ExcelProperty.class).index();
|
index = fields[i].getDeclaredAnnotation(ExcelProperty.class).index();
|
||||||
}
|
}
|
||||||
if (options.size() > 20) {
|
if (options.size() > 2) {
|
||||||
|
// 这里限制如果可选项大于20,则使用额外表形式
|
||||||
dropDownWithSheet(helper, workbook, sheet, index, options);
|
dropDownWithSheet(helper, workbook, sheet, index, options);
|
||||||
} else {
|
} else {
|
||||||
|
// 否则使用固定值形式
|
||||||
dropDownWithSimple(helper, sheet, index, options);
|
dropDownWithSimple(helper, sheet, index, options);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -105,7 +152,6 @@ public class ExcelDownHandler implements SheetWriteHandler {
|
|||||||
// 当一级选项个数不为空,使用默认形式
|
// 当一级选项个数不为空,使用默认形式
|
||||||
dropDownWithSimple(helper, sheet, everyOptions.getIndex(), everyOptions.getOptions());
|
dropDownWithSimple(helper, sheet, everyOptions.getIndex(), everyOptions.getOptions());
|
||||||
}
|
}
|
||||||
// 否则不做处理
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2,15 +2,17 @@ package com.ruoyi.demo.controller;
|
|||||||
|
|
||||||
import cn.dev33.satoken.annotation.SaIgnore;
|
import cn.dev33.satoken.annotation.SaIgnore;
|
||||||
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.collection.CollUtil;
|
||||||
|
import com.ruoyi.common.excel.ExcelResult;
|
||||||
import com.ruoyi.common.utils.poi.ExcelUtil;
|
import com.ruoyi.common.utils.poi.ExcelUtil;
|
||||||
|
import com.ruoyi.demo.domain.vo.ExportDemoVo;
|
||||||
|
import com.ruoyi.demo.listener.ExportDemoListener;
|
||||||
import com.ruoyi.demo.service.IExportExcelService;
|
import com.ruoyi.demo.service.IExportExcelService;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -94,6 +96,17 @@ public class TestExcelController {
|
|||||||
exportExcelService.exportWithOptions(response);
|
exportExcelService.exportWithOptions(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导入表格
|
||||||
|
*/
|
||||||
|
@SaIgnore
|
||||||
|
@PostMapping(value = "/importWithOptions", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
|
||||||
|
public List<ExportDemoVo> importWithOptions(@RequestPart("file") MultipartFile file) throws Exception {
|
||||||
|
// 处理解析结果
|
||||||
|
ExcelResult<ExportDemoVo> excelResult = ExcelUtil.importExcel(file.getInputStream(), ExportDemoVo.class, new ExportDemoListener());
|
||||||
|
return excelResult.getList();
|
||||||
|
}
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
static class TestObj1 {
|
static class TestObj1 {
|
||||||
|
|||||||
@ -2,11 +2,20 @@ package com.ruoyi.demo.domain.vo;
|
|||||||
|
|
||||||
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
||||||
import com.alibaba.excel.annotation.ExcelProperty;
|
import com.alibaba.excel.annotation.ExcelProperty;
|
||||||
import com.ruoyi.common.annotation.DropDown;
|
import com.ruoyi.common.annotation.ExcelDictFormat;
|
||||||
|
import com.ruoyi.common.annotation.ExcelEnumFormat;
|
||||||
|
import com.ruoyi.common.convert.ExcelDictConvert;
|
||||||
|
import com.ruoyi.common.convert.ExcelEnumConvert;
|
||||||
|
import com.ruoyi.common.core.validate.AddGroup;
|
||||||
|
import com.ruoyi.common.core.validate.EditGroup;
|
||||||
|
import com.ruoyi.common.enums.UserStatus;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotEmpty;
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 带有下拉选的Excel导出
|
* 带有下拉选的Excel导出
|
||||||
*
|
*
|
||||||
@ -23,46 +32,59 @@ public class ExportDemoVo {
|
|||||||
/**
|
/**
|
||||||
* 用户昵称
|
* 用户昵称
|
||||||
*/
|
*/
|
||||||
@ExcelProperty(value = "用户昵称", index = 0)
|
@ExcelProperty(value = "用户名", index = 0)
|
||||||
|
@NotEmpty(message = "用户名不能为空", groups = AddGroup.class)
|
||||||
private String nickName;
|
private String nickName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户类型
|
||||||
|
* </p>
|
||||||
|
* 使用ExcelEnumFormat注解需要进行下拉选的部分
|
||||||
|
*/
|
||||||
|
@ExcelProperty(value = "用户类型", index = 1, converter = ExcelEnumConvert.class)
|
||||||
|
@ExcelEnumFormat(enumClass = UserStatus.class, textField = "info")
|
||||||
|
@NotEmpty(message = "用户类型不能为空", groups = AddGroup.class)
|
||||||
|
private String userStatus;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 性别
|
* 性别
|
||||||
* <p>
|
* <p>
|
||||||
* 使用DropDown形式注入的下拉选可以使用任意形式,自己能解析出来就行
|
* 使用ExcelDictFormat注解需要进行下拉选的部分
|
||||||
*/
|
*/
|
||||||
@ExcelProperty(value = "性别", index = 1)
|
@ExcelProperty(value = "性别", index = 2, converter = ExcelDictConvert.class)
|
||||||
@DropDown({"1=男", "2=女"})
|
@ExcelDictFormat(dictType = "sys_user_sex")
|
||||||
private String genderStr;
|
@NotEmpty(message = "性别不能为空", groups = AddGroup.class)
|
||||||
|
private String gender;
|
||||||
/**
|
|
||||||
* 数据库中的性别
|
|
||||||
*/
|
|
||||||
private Integer gender;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 手机号
|
* 手机号
|
||||||
*/
|
*/
|
||||||
@ExcelProperty(value = "手机号", index = 2)
|
@ExcelProperty(value = "手机号", index = 3)
|
||||||
|
@NotEmpty(message = "手机号不能为空", groups = AddGroup.class)
|
||||||
private String phoneNumber;
|
private String phoneNumber;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Email
|
* Email
|
||||||
*/
|
*/
|
||||||
@ExcelProperty(value = "Email", index = 3)
|
@ExcelProperty(value = "Email", index = 4)
|
||||||
|
@NotEmpty(message = "Email不能为空", groups = AddGroup.class)
|
||||||
private String email;
|
private String email;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 省
|
* 省
|
||||||
* <p>
|
* <p>
|
||||||
* 级联下拉
|
* 级联下拉,仅判断是否选了
|
||||||
*/
|
*/
|
||||||
@ExcelProperty(value = "省", index = 25)
|
@ExcelProperty(value = "省", index = 5)
|
||||||
|
@NotNull(message = "省不能为空", groups = AddGroup.class)
|
||||||
private String province;
|
private String province;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 数据库中的省ID
|
* 数据库中的省ID
|
||||||
|
* </p>
|
||||||
|
* 处理完毕后再判断是否市正确的值
|
||||||
*/
|
*/
|
||||||
|
@NotNull(message = "请勿手动输入", groups = EditGroup.class)
|
||||||
private Integer provinceId;
|
private Integer provinceId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -70,12 +92,14 @@ public class ExportDemoVo {
|
|||||||
* <p>
|
* <p>
|
||||||
* 级联下拉
|
* 级联下拉
|
||||||
*/
|
*/
|
||||||
@ExcelProperty(value = "市", index = 26)
|
@ExcelProperty(value = "市", index = 6)
|
||||||
|
@NotNull(message = "市不能为空", groups = AddGroup.class)
|
||||||
private String city;
|
private String city;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 数据库中的市ID
|
* 数据库中的市ID
|
||||||
*/
|
*/
|
||||||
|
@NotNull(message = "请勿手动输入", groups = EditGroup.class)
|
||||||
private Integer cityId;
|
private Integer cityId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -83,11 +107,13 @@ public class ExportDemoVo {
|
|||||||
* <p>
|
* <p>
|
||||||
* 级联下拉
|
* 级联下拉
|
||||||
*/
|
*/
|
||||||
@ExcelProperty(value = "县", index = 27)
|
@ExcelProperty(value = "县", index = 7)
|
||||||
|
@NotNull(message = "县不能为空", groups = AddGroup.class)
|
||||||
private String area;
|
private String area;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 数据库中的县ID
|
* 数据库中的县ID
|
||||||
*/
|
*/
|
||||||
|
@NotNull(message = "请勿手动输入", groups = EditGroup.class)
|
||||||
private Integer areaId;
|
private Integer areaId;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,68 @@
|
|||||||
|
package com.ruoyi.demo.listener;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.NumberUtil;
|
||||||
|
import com.alibaba.excel.context.AnalysisContext;
|
||||||
|
import com.ruoyi.common.core.validate.AddGroup;
|
||||||
|
import com.ruoyi.common.core.validate.EditGroup;
|
||||||
|
import com.ruoyi.common.excel.DefaultExcelListener;
|
||||||
|
import com.ruoyi.common.excel.DropDownOptions;
|
||||||
|
import com.ruoyi.common.utils.ValidatorUtils;
|
||||||
|
import com.ruoyi.demo.domain.vo.ExportDemoVo;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Excel带下拉框的解析处理器
|
||||||
|
*
|
||||||
|
* @author Emil.Zhang
|
||||||
|
*/
|
||||||
|
public class ExportDemoListener extends DefaultExcelListener<ExportDemoVo> {
|
||||||
|
|
||||||
|
public ExportDemoListener() {
|
||||||
|
// 显示使用构造函数,否则将导致空指针
|
||||||
|
super(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void invoke(ExportDemoVo data, AnalysisContext context) {
|
||||||
|
// 先校验必填
|
||||||
|
ValidatorUtils.validate(data, AddGroup.class);
|
||||||
|
|
||||||
|
// 处理级联下拉的部分
|
||||||
|
String province = data.getProvince();
|
||||||
|
String city = data.getCity();
|
||||||
|
String area = data.getArea();
|
||||||
|
// 本行用户选择的省
|
||||||
|
List<String> thisRowSelectedProvinceOption = DropDownOptions.analyzeOptionValue(province);
|
||||||
|
if (thisRowSelectedProvinceOption.size() == 2) {
|
||||||
|
String provinceIdStr = thisRowSelectedProvinceOption.get(1);
|
||||||
|
if (NumberUtil.isNumber(provinceIdStr)) {
|
||||||
|
// 严格要求数据的话可以在这里做与数据库相关的判断
|
||||||
|
// 例如判断省信息是否在数据库中存在等,建议结合RedisCache做缓存10s,减少数据库调用
|
||||||
|
data.setProvinceId(Integer.parseInt(provinceIdStr));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 本行用户选择的市
|
||||||
|
List<String> thisRowSelectedCityOption = DropDownOptions.analyzeOptionValue(city);
|
||||||
|
if (thisRowSelectedCityOption.size() == 2) {
|
||||||
|
String cityIdStr = thisRowSelectedCityOption.get(1);
|
||||||
|
if (NumberUtil.isNumber(cityIdStr)) {
|
||||||
|
data.setCityId(Integer.parseInt(cityIdStr));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 本行用户选择的县
|
||||||
|
List<String> thisRowSelectedAreaOption = DropDownOptions.analyzeOptionValue(area);
|
||||||
|
if (thisRowSelectedAreaOption.size() == 2) {
|
||||||
|
String areaIdStr = thisRowSelectedAreaOption.get(1);
|
||||||
|
if (NumberUtil.isNumber(areaIdStr)) {
|
||||||
|
data.setAreaId(Integer.parseInt(areaIdStr));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理完毕以后判断是否符合规则
|
||||||
|
ValidatorUtils.validate(data, EditGroup.class);
|
||||||
|
|
||||||
|
// 添加到处理结果中
|
||||||
|
getExcelResult().getList().add(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,5 +1,6 @@
|
|||||||
package com.ruoyi.demo.service.impl;
|
package com.ruoyi.demo.service.impl;
|
||||||
|
|
||||||
|
import com.ruoyi.common.enums.UserStatus;
|
||||||
import com.ruoyi.common.excel.DropDownOptions;
|
import com.ruoyi.common.excel.DropDownOptions;
|
||||||
import com.ruoyi.common.utils.poi.ExcelUtil;
|
import com.ruoyi.common.utils.poi.ExcelUtil;
|
||||||
import com.ruoyi.demo.domain.vo.ExportDemoVo;
|
import com.ruoyi.demo.domain.vo.ExportDemoVo;
|
||||||
@ -32,7 +33,8 @@ public class ExportExcelServiceImpl implements IExportExcelService {
|
|||||||
// 模拟数据库中的一条数据
|
// 模拟数据库中的一条数据
|
||||||
ExportDemoVo everyRowData = new ExportDemoVo();
|
ExportDemoVo everyRowData = new ExportDemoVo();
|
||||||
everyRowData.setNickName("用户-" + i);
|
everyRowData.setNickName("用户-" + i);
|
||||||
everyRowData.setGender(1);
|
everyRowData.setUserStatus(UserStatus.OK.getCode());
|
||||||
|
everyRowData.setGender("1");
|
||||||
everyRowData.setPhoneNumber(String.format("175%08d", i));
|
everyRowData.setPhoneNumber(String.format("175%08d", i));
|
||||||
everyRowData.setEmail(String.format("175%08d", i) + "@163.com");
|
everyRowData.setEmail(String.format("175%08d", i) + "@163.com");
|
||||||
everyRowData.setProvinceId(i);
|
everyRowData.setProvinceId(i);
|
||||||
@ -105,17 +107,17 @@ public class ExportExcelServiceImpl implements IExportExcelService {
|
|||||||
// 创建省-市级联
|
// 创建省-市级联
|
||||||
DropDownOptions provinceToCity = new DropDownOptions();
|
DropDownOptions provinceToCity = new DropDownOptions();
|
||||||
// 以省为一级
|
// 以省为一级
|
||||||
provinceToCity.setIndex(25);
|
provinceToCity.setIndex(5);
|
||||||
// 以市为二级
|
// 以市为二级
|
||||||
provinceToCity.setNextIndex(26);
|
provinceToCity.setNextIndex(6);
|
||||||
// 补充省的内容以及市的内容
|
// 补充省的内容以及市的内容
|
||||||
provinceToCity.setOptions(provinceOptions);
|
provinceToCity.setOptions(provinceOptions);
|
||||||
provinceToCity.setNextOptions(provinceToCityOptions);
|
provinceToCity.setNextOptions(provinceToCityOptions);
|
||||||
|
|
||||||
// 创建市-县级联
|
// 创建市-县级联
|
||||||
DropDownOptions cityToArea = new DropDownOptions();
|
DropDownOptions cityToArea = new DropDownOptions();
|
||||||
cityToArea.setIndex(26);
|
cityToArea.setIndex(6);
|
||||||
cityToArea.setNextIndex(27);
|
cityToArea.setNextIndex(7);
|
||||||
cityToArea.setOptions(cityOptions);
|
cityToArea.setOptions(cityOptions);
|
||||||
cityToArea.setNextOptions(cityToAreaOptions);
|
cityToArea.setNextOptions(cityToAreaOptions);
|
||||||
|
|
||||||
@ -128,12 +130,7 @@ public class ExportExcelServiceImpl implements IExportExcelService {
|
|||||||
|
|
||||||
// 接下来需要将Excel中的展示数据转换为对应的下拉选
|
// 接下来需要将Excel中的展示数据转换为对应的下拉选
|
||||||
List<ExportDemoVo> outList = excelDataList.stream().map(everyRowData -> {
|
List<ExportDemoVo> outList = excelDataList.stream().map(everyRowData -> {
|
||||||
// 首先转换性别,性别是通过注解的,则自行提取为对应的值
|
// 只需要处理没有使用@ExcelDictFormat注解的下拉框
|
||||||
// 业务逻辑中一般会使用枚举的形式,这里直接通过判断值的形式拼接
|
|
||||||
Integer gender = everyRowData.getGender();
|
|
||||||
everyRowData.setGenderStr(gender == 1 ? "1=男" : "2=女");
|
|
||||||
|
|
||||||
// 下面处理下拉框的问题,对于数据本身只需要将对应的下拉值转换为下拉选以选中的选项
|
|
||||||
// 一般来说,可以直接在数据库查询即查询出省市县信息,这里通过模拟操作赋值
|
// 一般来说,可以直接在数据库查询即查询出省市县信息,这里通过模拟操作赋值
|
||||||
everyRowData.setProvince(buildOptions(provinceList, everyRowData.getProvinceId()));
|
everyRowData.setProvince(buildOptions(provinceList, everyRowData.getProvinceId()));
|
||||||
everyRowData.setCity(buildOptions(cityList, everyRowData.getCityId()));
|
everyRowData.setCity(buildOptions(cityList, everyRowData.getCityId()));
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import com.ruoyi.common.core.domain.PageQuery;
|
|||||||
import com.ruoyi.common.core.domain.entity.SysDictData;
|
import com.ruoyi.common.core.domain.entity.SysDictData;
|
||||||
import com.ruoyi.common.core.domain.entity.SysDictType;
|
import com.ruoyi.common.core.domain.entity.SysDictType;
|
||||||
import com.ruoyi.common.core.page.TableDataInfo;
|
import com.ruoyi.common.core.page.TableDataInfo;
|
||||||
|
import com.ruoyi.common.core.service.DictService;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -12,7 +13,7 @@ import java.util.List;
|
|||||||
*
|
*
|
||||||
* @author Lion Li
|
* @author Lion Li
|
||||||
*/
|
*/
|
||||||
public interface ISysDictTypeService {
|
public interface ISysDictTypeService extends DictService {
|
||||||
|
|
||||||
|
|
||||||
TableDataInfo<SysDictType> selectPageDictTypeList(SysDictType dictType, PageQuery pageQuery);
|
TableDataInfo<SysDictType> selectPageDictTypeList(SysDictType dictType, PageQuery pageQuery);
|
||||||
@ -32,14 +33,6 @@ public interface ISysDictTypeService {
|
|||||||
*/
|
*/
|
||||||
List<SysDictType> selectDictTypeAll();
|
List<SysDictType> selectDictTypeAll();
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据字典类型查询字典数据
|
|
||||||
*
|
|
||||||
* @param dictType 字典类型
|
|
||||||
* @return 字典数据集合信息
|
|
||||||
*/
|
|
||||||
List<SysDictData> selectDictDataByType(String dictType);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据字典类型ID查询信息
|
* 根据字典类型ID查询信息
|
||||||
*
|
*
|
||||||
|
|||||||
@ -38,7 +38,7 @@ import java.util.stream.Collectors;
|
|||||||
*/
|
*/
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@Service
|
@Service
|
||||||
public class SysDictTypeServiceImpl implements ISysDictTypeService, DictService {
|
public class SysDictTypeServiceImpl implements ISysDictTypeService {
|
||||||
|
|
||||||
private final SysDictTypeMapper baseMapper;
|
private final SysDictTypeMapper baseMapper;
|
||||||
private final SysDictDataMapper dictDataMapper;
|
private final SysDictDataMapper dictDataMapper;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user