Browse Source

【灵山街道】1.导入接口,增加表头预校验

master
wxz 2 years ago
parent
commit
23295fd158
  1. 2
      epmet-user/epmet-user-server/src/main/java/com/epmet/controller/LingShanSpecialCrowdController.java
  2. 44
      epmet-user/epmet-user-server/src/main/java/com/epmet/excel/handler/AbstractLingShanSpecialCrowdExcelImportListener.java
  3. 7
      epmet-user/epmet-user-server/src/main/java/com/epmet/exceptions/ReadExcelHeaderOnlyException.java
  4. 32
      epmet-user/epmet-user-server/src/main/java/com/epmet/service/impl/LingShanSpecialCrowdServiceImpl.java
  5. 3
      epmet-user/epmet-user-server/src/main/resources/mapper/LingshanSpecialCrowdDetailXfryDao.xml

2
epmet-user/epmet-user-server/src/main/java/com/epmet/controller/LingShanSpecialCrowdController.java

@ -67,7 +67,7 @@ public class LingShanSpecialCrowdController {
deleteSpecialCrowdTempFile(fileSavePath); deleteSpecialCrowdTempFile(fileSavePath);
} }
return null; return new Result();
} }
/** /**

44
epmet-user/epmet-user-server/src/main/java/com/epmet/excel/handler/AbstractLingShanSpecialCrowdExcelImportListener.java

@ -1,5 +1,6 @@
package com.epmet.excel.handler; package com.epmet.excel.handler;
import cn.hutool.log.Log;
import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener; import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.metadata.data.ReadCellData; import com.alibaba.excel.metadata.data.ReadCellData;
@ -23,7 +24,10 @@ import com.epmet.entity.LingshanSpecialCrowdPersonEntity;
import com.epmet.entity.LingshanSpecialCrowdPersonTypeEntity; import com.epmet.entity.LingshanSpecialCrowdPersonTypeEntity;
import com.epmet.enums.LingShanSpecialCrowdTypeEnums; import com.epmet.enums.LingShanSpecialCrowdTypeEnums;
import com.epmet.excel.data.LingShanSpecialCrowdDetailBaseExcelData; import com.epmet.excel.data.LingShanSpecialCrowdDetailBaseExcelData;
import com.epmet.exceptions.ReadExcelHeaderOnlyException;
import com.epmet.service.LingShanSpecialCrowdService; import com.epmet.service.LingShanSpecialCrowdService;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.ListUtils; import org.apache.commons.collections4.ListUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
@ -35,6 +39,8 @@ import java.util.stream.Collectors;
/** /**
* 灵山大屏-抽象的导入excel监听器 * 灵山大屏-抽象的导入excel监听器
*/ */
@Data
@Slf4j
public abstract class AbstractLingShanSpecialCrowdExcelImportListener<T extends LingShanSpecialCrowdDetailBaseExcelData, E extends LingshanSpecialCrowdDetailBaseEntity> public abstract class AbstractLingShanSpecialCrowdExcelImportListener<T extends LingShanSpecialCrowdDetailBaseExcelData, E extends LingshanSpecialCrowdDetailBaseEntity>
extends AnalysisEventListener<T> { extends AnalysisEventListener<T> {
@ -62,6 +68,15 @@ public abstract class AbstractLingShanSpecialCrowdExcelImportListener<T extends
*/ */
private List<String> headerZhList; private List<String> headerZhList;
/**
* @description: 是否只校验表头
* @param null:
* @return
* @author: WangXianZhang
* @date: 2023/4/19 5:16 PM
*/
private Boolean validateHeaderOnly = false;
/** /**
* 当前表头读到了第几行 * 当前表头读到了第几行
*/ */
@ -121,20 +136,37 @@ public abstract class AbstractLingShanSpecialCrowdExcelImportListener<T extends
if ((++currentHeadRowNum).equals(maxHeadRowNum)) { if ((++currentHeadRowNum).equals(maxHeadRowNum)) {
// 如果是表头最后一行,则校验表头 // 如果是表头最后一行,则校验表头
List<String> redundentHeaders = new ArrayList<>();
List<String> lackHeaders = new ArrayList<>();
Collection<String> headersFromFile = headMap.values(); Collection<String> headersFromFile = headMap.values();
// 2次循环,双向校验 // 2次循环,双向校验
for (String headerZh : headersFromFile) { for (String headerZh : headersFromFile) {
if (StringUtils.isNotBlank(headerZh) && !headerZhList.contains(headerZh)) { if (StringUtils.isNotBlank(headerZh) && !headerZhList.contains(headerZh)) {
throw new EpmetException("请确认表头内容与模板一致"); redundentHeaders.add(headerZh);
} }
} }
for (String headerZh : headerZhList) { for (String headerZh : headerZhList) {
if (StringUtils.isNotBlank(headerZh) && !headersFromFile.contains(headerZh)) { if (StringUtils.isNotBlank(headerZh) && !headersFromFile.contains(headerZh)) {
throw new EpmetException("请确认表头内容与模板一致"); lackHeaders.add(headerZh);
} }
} }
// 汇总错误字段,成一句话
String preValidTipStr = "";
if (CollectionUtils.isNotEmpty(redundentHeaders)) {
preValidTipStr += "多余【" + String.join(",", redundentHeaders) + "】字段。";
}
if (CollectionUtils.isNotEmpty(lackHeaders)) {
preValidTipStr += "缺少【" + String.join(",", lackHeaders) + "】必填字段。";
}
if (StringUtils.isNotBlank(preValidTipStr)) {
log.error("【灵山街道-社会维稳导入】表格表头不对应," + preValidTipStr);
throw new EpmetException(EpmetErrorCode.EPMET_COMMON_OPERATION_FAIL.getCode(), null, "上传文件有误!" + preValidTipStr + "请确认表格格式正确");
}
} }
} }
@ -148,6 +180,10 @@ public abstract class AbstractLingShanSpecialCrowdExcelImportListener<T extends
*/ */
@Override @Override
public void invoke(T row, AnalysisContext context) { public void invoke(T row, AnalysisContext context) {
if (validateHeaderOnly) {
// 如果仅解析表头,那么抛出异常,外层接住
throw new ReadExcelHeaderOnlyException();
}
try { try {
ValidatorUtils.validateEntity(row); ValidatorUtils.validateEntity(row);
} catch ( } catch (
@ -168,6 +204,10 @@ public abstract class AbstractLingShanSpecialCrowdExcelImportListener<T extends
@Override @Override
public void doAfterAllAnalysed(AnalysisContext context) { public void doAfterAllAnalysed(AnalysisContext context) {
if (validateHeaderOnly) {
throw new ReadExcelHeaderOnlyException();
}
if (originDatas.size() > 0) { if (originDatas.size() > 0) {
saveBatchWithLock(); saveBatchWithLock();
clear(); clear();

7
epmet-user/epmet-user-server/src/main/java/com/epmet/exceptions/ReadExcelHeaderOnlyException.java

@ -0,0 +1,7 @@
package com.epmet.exceptions;
/**
* 只解析表头的异常(用于停止excel导入)
*/
public class ReadExcelHeaderOnlyException extends RuntimeException {
}

32
epmet-user/epmet-user-server/src/main/java/com/epmet/service/impl/LingShanSpecialCrowdServiceImpl.java

@ -7,23 +7,29 @@ import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.read.metadata.ReadSheet; import com.alibaba.excel.read.metadata.ReadSheet;
import com.epmet.commons.tools.exception.EpmetErrorCode; import com.epmet.commons.tools.exception.EpmetErrorCode;
import com.epmet.commons.tools.exception.EpmetException; import com.epmet.commons.tools.exception.EpmetException;
import com.epmet.commons.tools.exception.ValidateException;
import com.epmet.commons.tools.utils.EpmetRequestHolder; import com.epmet.commons.tools.utils.EpmetRequestHolder;
import com.epmet.dao.*; import com.epmet.dao.*;
import com.epmet.entity.*; import com.epmet.entity.*;
import com.epmet.enums.LingShanSpecialCrowdTypeEnums; import com.epmet.enums.LingShanSpecialCrowdTypeEnums;
import com.epmet.excel.data.*; import com.epmet.excel.data.*;
import com.epmet.excel.handler.*; import com.epmet.excel.handler.*;
import com.epmet.exceptions.ReadExcelHeaderOnlyException;
import com.epmet.service.LingShanSpecialCrowdService; import com.epmet.service.LingShanSpecialCrowdService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.ListUtils; import org.apache.commons.collections4.ListUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.io.File; import java.io.File;
import java.util.List; import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
/** /**
* 灵山特殊人群service * 灵山特殊人群service
*/ */
@Slf4j
@Service @Service
public class LingShanSpecialCrowdServiceImpl implements LingShanSpecialCrowdService { public class LingShanSpecialCrowdServiceImpl implements LingShanSpecialCrowdService {
@ -51,6 +57,9 @@ public class LingShanSpecialCrowdServiceImpl implements LingShanSpecialCrowdServ
@Autowired @Autowired
private IcResiUserDao icResiUserDao; private IcResiUserDao icResiUserDao;
@Autowired
private ExecutorService executorService;
@Override @Override
public void importSpecialCrowd(String crowdCategory, String fileSavePath) { public void importSpecialCrowd(String crowdCategory, String fileSavePath) {
Class<? extends LingShanSpecialCrowdDetailBaseExcelData> excelDataClass; Class<? extends LingShanSpecialCrowdDetailBaseExcelData> excelDataClass;
@ -85,10 +94,25 @@ public class LingShanSpecialCrowdServiceImpl implements LingShanSpecialCrowdServ
// ReadSheet sheet = EasyExcel.readSheet(0).registerReadListener(listener).build(); // ReadSheet sheet = EasyExcel.readSheet(0).registerReadListener(listener).build();
// EasyExcel.read(fileSavePath).build().read(sheet); // EasyExcel.read(fileSavePath).build().read(sheet);
EasyExcel.read(fileSavePath, excelDataClass, listener) // 解析表头,判断表头是否合格
.headRowNumber(specialCrowdTypeEnum.getHeaderRowNumber()) try {
.sheet(0) listener.setValidateHeaderOnly(true);
.doRead(); EasyExcel.read(fileSavePath, excelDataClass, listener)
.headRowNumber(specialCrowdTypeEnum.getHeaderRowNumber())
.sheet(0)
.doRead();
} catch (ReadExcelHeaderOnlyException e) {
log.info("【灵山街道-导入社会维稳】验证通过,可以继续导入");
}
// 正式开始导入。异步导入
listener.setValidateHeaderOnly(false);
CompletableFuture.runAsync(() -> {
EasyExcel.read(fileSavePath, excelDataClass, listener)
.headRowNumber(specialCrowdTypeEnum.getHeaderRowNumber())
.sheet(0)
.doRead();
}, executorService);
} }
@Override @Override

3
epmet-user/epmet-user-server/src/main/resources/mapper/LingshanSpecialCrowdDetailXfryDao.xml

@ -51,8 +51,7 @@
, PRINCIPAL_CONTACT = values(PRINCIPAL_CONTACT) , PRINCIPAL_CONTACT = values(PRINCIPAL_CONTACT)
, STABLE_CONTROLER_LIST = values(STABLE_CONTROLER_LIST) , STABLE_CONTROLER_LIST = values(STABLE_CONTROLER_LIST)
, DEL_FLAG = values(DEL_FLAG) , DEL_FLAG = values(DEL_FLAG)
, REVISION = values(REVISION), CREATED_BY = values(CREATED_BY) , REVISION = values(REVISION)
, CREATED_TIME = values(CREATED_TIME)
, UPDATED_BY = values(UPDATED_BY) , UPDATED_BY = values(UPDATED_BY)
, UPDATED_TIME = values(UPDATED_TIME) , UPDATED_TIME = values(UPDATED_TIME)
</insert> </insert>

Loading…
Cancel
Save