字典转换实现方案变更
This commit is contained in:
parent
691504139f
commit
64ac6f0d80
|
@ -59,8 +59,11 @@ public abstract class BaseExcelFileController extends BaseFileController {
|
|||
* @throws Exception
|
||||
*/
|
||||
public JsonResult excelPreview(MultipartFile file) throws Exception {
|
||||
Map<String, Object> dataMap = new HashMap(16);
|
||||
savePreviewExcelFile(file, dataMap);
|
||||
checkIsExcel(file);
|
||||
// 保存文件到本地
|
||||
UploadFile uploadFile = super.saveFile(file, getExcelDataListener().getExcelModelClass());
|
||||
// 构建预览数据Map
|
||||
Map<String, Object> dataMap = buildPreviewDataMap(uploadFile, file.getOriginalFilename());
|
||||
return JsonResult.OK(dataMap);
|
||||
}
|
||||
|
||||
|
@ -71,8 +74,11 @@ public abstract class BaseExcelFileController extends BaseFileController {
|
|||
* @throws Exception
|
||||
*/
|
||||
public JsonResult excelPreview(UploadFileFormDTO uploadFileFormDTO) throws Exception {
|
||||
Map<String, Object> dataMap = new HashMap(16);
|
||||
savePreviewExcelFile(uploadFileFormDTO, dataMap);
|
||||
checkIsExcel(uploadFileFormDTO.getFile());
|
||||
// 保存文件到本地
|
||||
UploadFile uploadFile = super.saveFile(uploadFileFormDTO);
|
||||
// 构建预览数据Map
|
||||
Map<String, Object> dataMap = buildPreviewDataMap(uploadFile, uploadFileFormDTO.getFile().getOriginalFilename());
|
||||
return JsonResult.OK(dataMap);
|
||||
}
|
||||
|
||||
|
@ -151,21 +157,21 @@ public abstract class BaseExcelFileController extends BaseFileController {
|
|||
}
|
||||
|
||||
/**
|
||||
* 保存上传文件
|
||||
*
|
||||
* 构建预览数据Map
|
||||
* @param uploadFile
|
||||
* @param originFileName
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
private void savePreviewExcelFile(MultipartFile file, Map<String, Object> dataMap) throws Exception {
|
||||
checkIsExcel(file);
|
||||
// 保存文件到本地
|
||||
UploadFile uploadFile = super.saveFile(file, getExcelDataListener().getExcelModelClass());
|
||||
private Map<String, Object> buildPreviewDataMap(UploadFile uploadFile, String originFileName) throws Exception{
|
||||
Map<String, Object> dataMap = new HashMap<>(8);
|
||||
// 预览
|
||||
FixedHeadExcelListener listener = getExcelDataListener();
|
||||
listener.setRequestParams(super.getParamsMap());
|
||||
try {
|
||||
ExcelHelper.previewReadExcel(uploadFile.getStoragePath(), listener);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.warn("解析并校验excel文件失败", e);
|
||||
if (V.notEmpty(e.getMessage())) {
|
||||
throw new Exception(e.getMessage());
|
||||
|
@ -174,41 +180,7 @@ public abstract class BaseExcelFileController extends BaseFileController {
|
|||
}
|
||||
// 绑定属性到model
|
||||
dataMap.put("header", listener.getFieldHeaders());
|
||||
dataMap.put(ORIGIN_FILE_NAME, file.getOriginalFilename());
|
||||
dataMap.put(PREVIEW_FILE_NAME, FileHelper.getFileName(uploadFile.getStoragePath()));
|
||||
List dataList = listener.getDataList();
|
||||
if (V.notEmpty(dataList) && dataList.size() > BaseConfig.getPageSize()) {
|
||||
dataList = dataList.subList(0, BaseConfig.getPageSize());
|
||||
}
|
||||
//最多返回前端十条数据
|
||||
dataMap.put("dataList", dataList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存上传文件
|
||||
*
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
private void savePreviewExcelFile(UploadFileFormDTO uploadFileFormDTO, Map<String, Object> dataMap) throws Exception {
|
||||
checkIsExcel(uploadFileFormDTO.getFile());
|
||||
// 保存文件到本地
|
||||
UploadFile uploadFile = super.saveFile(uploadFileFormDTO);
|
||||
// 预览
|
||||
FixedHeadExcelListener listener = getExcelDataListener();
|
||||
listener.setRequestParams(super.getParamsMap());
|
||||
try {
|
||||
ExcelHelper.previewReadExcel(uploadFile.getStoragePath(), listener);
|
||||
} catch (Exception e) {
|
||||
log.warn("解析并校验excel文件失败", e);
|
||||
if (V.notEmpty(e.getMessage())) {
|
||||
throw new Exception(e.getMessage());
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
// 绑定属性到model
|
||||
dataMap.put("header", listener.getFieldHeaders());
|
||||
dataMap.put(ORIGIN_FILE_NAME, uploadFileFormDTO.getFile().getOriginalFilename());
|
||||
dataMap.put(ORIGIN_FILE_NAME, originFileName);
|
||||
dataMap.put(PREVIEW_FILE_NAME, FileHelper.getFileName(uploadFile.getStoragePath()));
|
||||
List dataList = listener.getDataList();
|
||||
if (V.notEmpty(dataList) && dataList.size() > BaseConfig.getPageSize()) {
|
||||
|
@ -216,6 +188,7 @@ public abstract class BaseExcelFileController extends BaseFileController {
|
|||
}
|
||||
//最多返回前端十条数据
|
||||
dataMap.put("dataList", dataList);
|
||||
return dataMap;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -25,12 +25,13 @@ import com.diboot.core.exception.BusinessException;
|
|||
import com.diboot.file.excel.cache.DictTempCache;
|
||||
|
||||
/**
|
||||
* 枚举转化器
|
||||
* 枚举转化器 (已废弃,不再需要指定)
|
||||
*
|
||||
* @author : uu
|
||||
* @version : v1.0
|
||||
* @Date 2020-01-07 16:53
|
||||
*/
|
||||
@Deprecated
|
||||
public class DictConverter implements Converter<String> {
|
||||
|
||||
@Override
|
||||
|
@ -45,25 +46,11 @@ public class DictConverter implements Converter<String> {
|
|||
|
||||
@Override
|
||||
public String convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception {
|
||||
// 注解
|
||||
BindDict bindDict = contentProperty.getField().getAnnotation(BindDict.class);
|
||||
if (bindDict == null) {
|
||||
throw new BusinessException("DictConverter依赖BindDict注解,请指定");
|
||||
}
|
||||
String dictValue = DictTempCache.getDictValue(bindDict.type(), cellData.getStringValue());
|
||||
if (dictValue == null) {
|
||||
throw new BusinessException("'" + cellData.getStringValue() + "' 无匹配字典定义");
|
||||
}
|
||||
return dictValue;
|
||||
return cellData.getStringValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CellData convertToExcelData(String value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception {
|
||||
// 注解
|
||||
BindDict bindDict = contentProperty.getField().getAnnotation(BindDict.class);
|
||||
if (bindDict == null) {
|
||||
throw new BusinessException("DictConverter依赖BindDict注解,请指定.");
|
||||
}
|
||||
return new CellData(DictTempCache.getDictLabel(bindDict.type(), value, contentProperty.getField().getDeclaringClass()));
|
||||
return new CellData(value);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,9 @@ import com.alibaba.excel.context.AnalysisContext;
|
|||
import com.alibaba.excel.event.AnalysisEventListener;
|
||||
import com.alibaba.excel.exception.ExcelDataConvertException;
|
||||
import com.alibaba.excel.metadata.Head;
|
||||
import com.alibaba.excel.metadata.property.ExcelContentProperty;
|
||||
import com.alibaba.excel.read.metadata.property.ExcelReadHeadProperty;
|
||||
import com.diboot.core.binding.annotation.BindDict;
|
||||
import com.diboot.core.exception.BusinessException;
|
||||
import com.diboot.core.util.BeanUtils;
|
||||
import com.diboot.core.util.S;
|
||||
|
@ -29,6 +31,7 @@ import com.diboot.file.excel.BaseExcelModel;
|
|||
import com.diboot.file.excel.cache.DictTempCache;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.*;
|
||||
|
||||
/***
|
||||
|
@ -82,25 +85,28 @@ public abstract class FixedHeadExcelListener<T extends BaseExcelModel> extends A
|
|||
**/
|
||||
@Override
|
||||
public void doAfterAllAnalysed(AnalysisContext context) {
|
||||
//表头和数据校验
|
||||
validateHeaderAndDataList();
|
||||
// 收集校验异常信息
|
||||
if(V.notEmpty(dataList)){
|
||||
//自定义数据校验
|
||||
additionalValidate(dataList, requestParams);
|
||||
// 提取校验结果
|
||||
dataList.stream().forEach(data->{
|
||||
if(V.notEmpty(data.getValidateError())){
|
||||
validateErrorMsgs.add(data.getRowIndex() + "行: " + data.getValidateError());
|
||||
}
|
||||
});
|
||||
if(V.isEmpty(dataList)){
|
||||
return;
|
||||
}
|
||||
// 收集校验异常信息
|
||||
//表头和数据校验
|
||||
validateHeaderAndDataList(context);
|
||||
// 检查或转换字典
|
||||
validateOrConvertDict(context);
|
||||
//自定义数据校验
|
||||
additionalValidate(dataList, requestParams);
|
||||
// 提取校验结果
|
||||
dataList.stream().forEach(data->{
|
||||
if(V.notEmpty(data.getValidateError())){
|
||||
validateErrorMsgs.add(data.getRowIndex() + "行: " + data.getValidateError());
|
||||
}
|
||||
});
|
||||
// 有错误 抛出异常
|
||||
if(V.notEmpty(this.validateErrorMsgs)){
|
||||
throw new BusinessException(Status.FAIL_VALIDATION, S.join(this.validateErrorMsgs, "; "));
|
||||
}
|
||||
// 保存
|
||||
if(preview == false && V.notEmpty(dataList)){
|
||||
if(preview == false){
|
||||
// 保存数据
|
||||
saveData(dataList, requestParams);
|
||||
}
|
||||
|
@ -155,15 +161,65 @@ public abstract class FixedHeadExcelListener<T extends BaseExcelModel> extends A
|
|||
/**
|
||||
* 校验表头, 校验数据实体list
|
||||
* */
|
||||
private void validateHeaderAndDataList() {
|
||||
private void validateHeaderAndDataList(AnalysisContext context) {
|
||||
// 校验数据是否合法
|
||||
if(V.notEmpty(dataList)){
|
||||
dataList.stream().forEach(data->{
|
||||
String errMsg = V.validateBean(data);
|
||||
if(V.notEmpty(errMsg)){
|
||||
data.addValidateError(errMsg);
|
||||
dataList.stream().forEach(data->{
|
||||
String errMsg = V.validateBean(data);
|
||||
if(V.notEmpty(errMsg)){
|
||||
data.addValidateError(errMsg);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验或转换字典name-value
|
||||
* @param context
|
||||
*/
|
||||
private void validateOrConvertDict(AnalysisContext context){
|
||||
Map<String, String> fieldName2DictTypeMap = null;
|
||||
Map<Integer, ExcelContentProperty> map = context.currentReadHolder().excelReadHeadProperty().getContentPropertyMap();
|
||||
for(Map.Entry<Integer, ExcelContentProperty> entry : map.entrySet()){
|
||||
// 注解
|
||||
Field field = entry.getValue().getField();
|
||||
BindDict bindDict = field.getAnnotation(BindDict.class);
|
||||
if (bindDict != null) {
|
||||
if(fieldName2DictTypeMap == null){
|
||||
fieldName2DictTypeMap = new HashMap<>(8);
|
||||
}
|
||||
});
|
||||
fieldName2DictTypeMap.put(field.getName(), bindDict.type());
|
||||
}
|
||||
}
|
||||
if(fieldName2DictTypeMap == null){
|
||||
return;
|
||||
}
|
||||
// 预览时只检查
|
||||
if(this.preview){
|
||||
for(T data : dataList){
|
||||
for(Map.Entry<String, String> entry: fieldName2DictTypeMap.entrySet()){
|
||||
String dictLabel = BeanUtils.getStringProperty(data, entry.getKey());
|
||||
if(V.notEmpty(dictLabel)){
|
||||
String dictValue = DictTempCache.getDictValue(entry.getValue(), dictLabel);
|
||||
if(dictValue == null){
|
||||
data.addValidateError(dictLabel + " 无匹配字典值");
|
||||
}
|
||||
}
|
||||
else{
|
||||
data.addValidateError(" 无匹配字典值");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 转换
|
||||
else{
|
||||
for(T data : dataList){
|
||||
for(Map.Entry<String, String> entry: fieldName2DictTypeMap.entrySet()){
|
||||
String dictLabel = BeanUtils.getStringProperty(data, entry.getKey());
|
||||
if(V.notEmpty(dictLabel)){
|
||||
String dictValue = DictTempCache.getDictValue(entry.getValue(), dictLabel);
|
||||
BeanUtils.setProperty(data, entry.getKey(), dictValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,6 @@ package com.diboot.file.example.custom;
|
|||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import com.diboot.core.binding.annotation.BindDict;
|
||||
import com.diboot.file.excel.BaseExcelModel;
|
||||
import com.diboot.file.excel.converter.DictConverter;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.hibernate.validator.constraints.Length;
|
||||
|
@ -52,7 +51,7 @@ public class DepartmentExcelModel extends BaseExcelModel {
|
|||
|
||||
@NotNull(message = "必须指定status")
|
||||
@BindDict(type = "USER_STATUS")
|
||||
@ExcelProperty(value = "状态", index = 4, converter = DictConverter.class)
|
||||
@ExcelProperty(value = "状态", index = 4)
|
||||
private String userStatus;
|
||||
|
||||
}
|
||||
|
|
|
@ -52,6 +52,7 @@ public class FixedHeadExcelReadTest extends ExcelWriteTest {
|
|||
Assert.assertTrue(success);
|
||||
System.out.println(JSON.stringify(listener.getFieldHeadMap()));
|
||||
System.out.println(JSON.stringify(listener.getDataList()));
|
||||
Assert.assertTrue(listener.getDataList().get(0).getUserStatus().equals("在职"));
|
||||
}
|
||||
catch (Exception e){
|
||||
e.printStackTrace();
|
||||
|
@ -81,5 +82,27 @@ public class FixedHeadExcelReadTest extends ExcelWriteTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNormalDataReadSave(){
|
||||
try{
|
||||
prepareNormalDataExcel();
|
||||
// 读且保存
|
||||
DepartmentImportListener listener = new DepartmentImportListener();
|
||||
boolean success = ExcelHelper.readAndSaveExcel(getTempFilePath(), listener);
|
||||
Assert.assertTrue(success);
|
||||
System.out.println(JSON.stringify(listener.getFieldHeadMap()));
|
||||
System.out.println(JSON.stringify(listener.getDataList()));
|
||||
Assert.assertTrue(listener.getDataList().get(0).getUserStatus().equals("A"));
|
||||
}
|
||||
catch (Exception e){
|
||||
e.printStackTrace();
|
||||
System.out.println(e.getMessage());
|
||||
Assert.fail();
|
||||
}
|
||||
finally {
|
||||
deleteTempFile();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue