字典转换实现方案变更

This commit is contained in:
mazhicheng 2020-07-01 12:42:03 +08:00
parent 691504139f
commit 64ac6f0d80
5 changed files with 123 additions and 85 deletions

View File

@ -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;
}
/**

View File

@ -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);
}
}

View File

@ -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);
}
}
}
}
}

View File

@ -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;
}

View File

@ -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();
}
}
}