1.需求说明
通过党组织全称和上级党组织全称作为数据唯一key更新其它数据。
2.添加 EasyExcel 依赖
<dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>2.1.6</version></dependency>
3.提供给前端的接口
publicLonguploadBatchUpdateOrgFile( ("file") MultipartFilefile) throwsIOException { Stringoperator=InvocationContexts.getContext().getUserId(); IccAssert.notNull(file, "上传的导入文件不能为空"); IccAssert.notEmpty(file.getOriginalFilename(), "上传的党组织文件名不能为空"); // 插入导入任务 ObExcelScheduleTasktaskParam=newObExcelScheduleTask(); // taskParam.set ... ObExcelScheduleTasktask=taskService.add(taskParam); if (task==null) { thrownewIccException(IccError.ICC_ERROR); } InputStreaminputStream=file.getInputStream(); // 启用线程池异步导入数据ThreadPoolBusService.IMPORT_TASK_POOL.submit(newRunnable() { publicvoidrun() { // 数据解析 实现AnalysisEventListenerOrgBatchUpdateExcelListenerorgBatchUpdateExcelListener=newOrgBatchUpdateExcelListener(commonDictService, orgQueryService, taskService, tenantCode, file.getOriginalFilename(), orgBusinessId, task, partyUserService); EasyExcel.read(inputStream, OrgBatchUpdateExcelModel.class, orgBatchUpdateExcelListener).sheet().doRead(); // 更新数据orgService.batchUpdateImportOrg(operator, tenantCode, file.getOriginalFilename(), task, orgBatchUpdateExcelListener.getSuccessResultList(), orgBatchUpdateExcelListener.getFailResultList()); } }); returntask.getId(); }
5.讲解AnalysisEventListener< T>
监听器有哪些方法
publicabstractclassAnalysisEventListener<T>implementsReadListener<T> { // 这是监听器的构造方法,一般我们可以通过构造方法传入一些我们需要在解析excel时使用的数据publicAnalysisEventListener() {} // 调用invokeHeadMap来获取表头数据publicvoidinvokeHead(Map<Integer, CellData>headMap, AnalysisContextcontext) { this.invokeHeadMap(ConverterUtils.convertToStringMap(headMap, context), context); } // 获取表头数据publicvoidinvokeHeadMap(Map<Integer, String>headMap, AnalysisContextcontext) {} // 读取条额外信息:批注、超链接、合并单元格信息等publicvoidextra(CellExtraextra, AnalysisContextcontext) {} // 在转换异常 获取其他异常下会调用本接口。抛出异常则停止读取。如果这里不抛出异常则 继续读取下一行。publicvoidonException(Exceptionexception, AnalysisContextcontext) throwsException {throwexception;} publicbooleanhasNext(AnalysisContextcontext) {returntrue;} }
其中可以看到AnalysisEventListener 实现了 ReadListener
然后看到ReadListener后 发现其中还有两个方法是AnalysisEventListener没有实现的,而且这两个方法还是很重要的
publicinterfaceReadListener<T>extendsListener { voidonException(Exceptionvar1, AnalysisContextvar2) throwsException; voidinvokeHead(Map<Integer, CellData>var1, AnalysisContextvar2); // 一行行读取表格内容voidinvoke(Tvar1, AnalysisContextvar2); voidextra(CellExtravar1, AnalysisContextvar2); // 读取完成后的操作voiddoAfterAllAnalysed(AnalysisContextvar1); booleanhasNext(AnalysisContextvar1); }
6.实现AnalysisEventListener过滤成功和失败的数据
publicclassOrgBatchUpdateExcelListenerextendsAnalysisEventListener<OrgBatchUpdateExcelModel> { privateCommonDictServicecommonDictService; privateOrgQueryServiceorgQueryService; privateTaskServicetaskService; privatePartyUserServicepartyUserService; privateObExcelScheduleTasktask; /*** 源文件名*/privateStringoriginalFilename; /*** 组织编码*/privateStringorgBusinessId; /*** 验证成功的数据*/privateList<OrgBatchUpdateExcelModel>successResultList; /*** 验证失败的数据*/privateList<OrgBatchUpdateExcelModel>failResultList; /*** 党组织类别*/privateMap<String, String>dzzlbRemarkMap; /*** 党组织所在行政区划*/privateMap<String, String>xzqhMap; /*** 党组织所在单位情况*/privateMap<String, String>dwqkMap; /*** 党组织类别*/privateMap<String, String>dzzlbMap; /*** 删除操作*/privatestaticfinalStringOPERATE_DELETE="删除"; /*** 修改操作*/privatestaticfinalStringOPERATE_UPDATE="修改"; privatestaticfinalStringEXCEL_HEAD_ERROR="文件不正确,请重新下载模板"; privatestaticfinalStringEXCEL_EMPTY_ERROR="文件里没有数据"; privatestaticfinalStringEXCEL_DATA_T00_LONG="excel里数据不能大于1000条"; /*** excel头*/privatestaticfinalStringHEAD="{0=党组织全称, 1=上级党组织全称, 2=党组织联系人, 3=党组织联系电话(手机号), 4=党组织类别, 5=党组织所在单位情况, 6=党组织所在行政区划, 7=主要业务, 8=操作}"; /*** excel头*/privatestaticfinalStringHEAD_TWO="{0=党组织全称, 1=上级党组织全称, 2=党组织联系人, 3=党组织联系电话(手机号), 4=党组织类别, 5=党组织所在单位情况, 6=党组织所在行政区划, 7=主要业务, 8=操作, 9=错误原因}"; /*** excel头*/privateMap<Integer, String>HEAD_MAP=null; /*** 导入的起始行*/privatestaticfinalIntegerSTART_ROW_INDEX=3; /*** 最大导入数量*/privatestaticfinalIntegerMAX_ROWS=1000; /*** 租户*/privateStringtenantCode; publicOrgBatchUpdateExcelListener(CommonDictServicecommonDictService, OrgQueryServiceorgQueryService, TaskServicetaskService, StringtenantCode, StringoriginalFilename, StringorgBusinessId, ObExcelScheduleTasktask, PartyUserServicepartyUserService) { this.commonDictService=commonDictService; this.orgQueryService=orgQueryService; this.taskService=taskService; this.tenantCode=tenantCode; this.originalFilename=originalFilename; this.orgBusinessId=orgBusinessId; this.task=task; this.partyUserService=partyUserService; init(); } privatevoidinit() { Map<String, String>dzzlbMap=commonDictService.getValueKeyByTypeCode(OrgConst.DICT_DZZ_ZZLB); Map<String, String>dzzlbRemarkMap=commonDictService.getValueRemarkByTypeCode(OrgConst.DICT_DZZ_ZZLB); Map<String, String>xzqhMap=commonDictService.getValueKeyByTypeCode(OrgConst.D_DZZ_XZQH); Map<String, String>dwqkMap=commonDictService.getValueKeyByTypeCode(OrgConst.D_DZZ_DWQK); this.dzzlbRemarkMap=dzzlbRemarkMap; this.xzqhMap=xzqhMap; this.dwqkMap=dwqkMap; this.dzzlbMap=dzzlbMap; this.successResultList=newArrayList<>(); this.failResultList=newArrayList<>(); } publicvoidinvokeHeadMap(Map<Integer, String>headMap, AnalysisContextcontext) { log.info("fileName:"+originalFilename); // 验证excel是否合规context.readSheetHolder().setHeadRowNumber(START_ROW_INDEX); HEAD_MAP=headMap; introwIndex=context.readRowHolder().getRowIndex(); if (rowIndex==START_ROW_INDEX-1) { Stringhead=String.valueOf(HEAD_MAP); if (!StringUtils.equals(head, HEAD) &&!StringUtils.equals(head, HEAD_TWO)) { log.info("head:{}", head); thrownewExcelAnalysisException(EXCEL_HEAD_ERROR); } inttotalRows=context.readSheetHolder().getApproximateTotalRowNumber(); if (totalRows<=START_ROW_INDEX) { thrownewExcelAnalysisException(EXCEL_EMPTY_ERROR); } if (totalRows-START_ROW_INDEX>MAX_ROWS) { thrownewExcelAnalysisException(EXCEL_DATA_T00_LONG); } } } publicvoidinvoke(OrgBatchUpdateExcelModelorgBatchUpdateExcelModel, AnalysisContextanalysisContext) { StringBuffererrorMsg=newStringBuffer(); introwIndex=analysisContext.readRowHolder().getRowIndex(); if (rowIndex>=START_ROW_INDEX) { log.info("====当前数据========:{}", orgBatchUpdateExcelModel); // 验证数据是否正确if (StringUtils.isBlank(orgBatchUpdateExcelModel.getOrgName())) { errorMsg.append("|党组织全称不能为空"); } if (StringUtils.isBlank(orgBatchUpdateExcelModel.getParentOrgName())) { errorMsg.append("|上级党组织全称不能为空"); } if (StringUtils.isBlank(orgBatchUpdateExcelModel.getOperate())) { errorMsg.append("|操作列不能未空"); } elseif (StringUtils.equals(orgBatchUpdateExcelModel.getOperate(), OPERATE_DELETE)) { // 删除orgBatchUpdateExcelModel.setDeleteFlag(OrgConst.YES_STATE); } else { // 更新Stringlinker=orgBatchUpdateExcelModel.getLinker(); StringlinkPhone=orgBatchUpdateExcelModel.getLinkPhone(); StringpartyTypeName=orgBatchUpdateExcelModel.getPartyTypeName(); StringpartyCompanyIntroName=orgBatchUpdateExcelModel.getPartyCompanyIntroName(); StringxzqhName=orgBatchUpdateExcelModel.getXzqhName(); StringmainBusiness=orgBatchUpdateExcelModel.getMainBusiness(); if (StringUtils.isBlank(linker) &&StringUtils.isBlank(linkPhone) &&StringUtils.isBlank(partyTypeName) &&StringUtils.isBlank(partyCompanyIntroName) &&StringUtils.isBlank(xzqhName) &&StringUtils.isBlank(mainBusiness)) { errorMsg.append("|请至少输入一个修改项"); } if (StringUtils.isNotBlank(linkPhone) &&!Validator.isMobile(linkPhone)) { errorMsg.append("|党组织联系电话格式错误"); } if (StringUtils.isNotBlank(partyTypeName)) { StringpartyType=dzzlbMap.get(orgBatchUpdateExcelModel.getPartyTypeName()); if (StringUtils.isBlank(partyType)) { errorMsg.append("|党组织类别错误"); } else { orgBatchUpdateExcelModel.setPartyType(partyType); orgBatchUpdateExcelModel.setPartyTypeSimple(dzzlbRemarkMap.get(orgBatchUpdateExcelModel.getPartyTypeName())); } } if (StringUtils.isNotBlank(partyCompanyIntroName)) { StringpartyCompanyIntro=dwqkMap.get(orgBatchUpdateExcelModel.getPartyCompanyIntroName()); if (StringUtils.isBlank(partyCompanyIntro)) { errorMsg.append("|党组织所在单位情况错误"); } else { orgBatchUpdateExcelModel.setPartyCompanyIntro(partyCompanyIntro); } } if (StringUtils.isNotBlank(xzqhName)) { Stringxzqh=xzqhMap.get(orgBatchUpdateExcelModel.getXzqhName()); if (StringUtils.isBlank(xzqh)) { errorMsg.append("|党组织所在行政区划错误"); } else { orgBatchUpdateExcelModel.setXzqh(xzqh); } } } StringerrorMsgStr=errorMsg.toString(); if (StringUtils.isNotBlank(errorMsgStr)) { orgBatchUpdateExcelModel.setErrorMsg(errorMsgStr); this.clear(orgBatchUpdateExcelModel); failResultList.add(orgBatchUpdateExcelModel); } else { successResultList.add(orgBatchUpdateExcelModel); } } } publicvoiddoAfterAllAnalysed(AnalysisContextanalysisContext) { if (CollectionUtils.isEmpty(successResultList) &&CollectionUtils.isEmpty(failResultList)) { thrownewExcelAnalysisException(EXCEL_EMPTY_ERROR); } if (!CollectionUtils.isEmpty(successResultList)) { List<String>orgNameList=successResultList.stream().map(e->e.getOrgName()).collect(Collectors.toList()); Stringpids=orgQueryService.getPids(orgBusinessId, tenantCode); List<ObOrgDTO>obOrgDTOList=orgQueryService.queryForBatchUpdateOrg(orgNameList, orgBusinessId, pids, tenantCode); // map 用来获取组织编码Map<String, ObOrgDTO>map=obOrgDTOList.stream() .collect(Collectors.toMap(ObOrgDTO::getOrgName, o->o, (v1, v2) ->v1)); // 上级党组织的信息List<String>pidList=obOrgDTOList.stream().map(e->e.getPid()).collect(Collectors.toList()); Map<String, ObPartyOrg>parentOrgMap=orgQueryService.batchQueryPartyOrg(pidList, tenantCode, OrgConst.NO_STATE); // 本级党组织的信息List<String>currentOrgIdList=obOrgDTOList.stream().map(e->e.getOrgBusinessId()).collect(Collectors.toList()); Map<String, ObPartyOrg>currentOrgMap=orgQueryService.batchQueryPartyOrg(currentOrgIdList, tenantCode, OrgConst.NO_STATE); booleanerrorFlag=false; for (OrgBatchUpdateExcelModelmodel : successResultList) { Stringkey=model.getOrgName() +model.getParentOrgName(); ObOrgDTOobOrgDTO=map.get(key); if (obOrgDTO!=null) { model.setOrgBusinessId(obOrgDTO.getOrgBusinessId()); if (StringUtils.equals(model.getPartyCompanyIntro(), OrgConst.IN_THE_SAME_COMPANY_CODE)) { model.setCompanyBusinessId(parentOrgMap.get(obOrgDTO.getPid()) ==null?null : parentOrgMap.get(obOrgDTO.getPid()).getCompanyBusinessId()); model.setCompanyType(parentOrgMap.get(obOrgDTO.getPid()) ==null?null : parentOrgMap.get(obOrgDTO.getPid()).getCompanyType()); } else { if (currentOrgMap.get(model.getOrgBusinessId()) !=null&&!StringUtils.equals(currentOrgMap.get(model.getOrgBusinessId()).getPartyCompanyIntro(), OrgConst.IN_THE_SAME_COMPANY_CODE)) { model.setCompanyType(currentOrgMap.get(model.getOrgBusinessId()).getCompanyType()); model.setCompanyBusinessId(currentOrgMap.get(model.getOrgBusinessId()).getOrgBusinessId()); } } if (OrgConst.YES_STATE.equals(model.getDeleteFlag())) { // 删除需要判断 下级有没有组织或党员List<String>childOrgBusinessId=orgQueryService.getAllChildOrgBusinessId(model.getOrgBusinessId(), tenantCode); if (!CollectionUtils.isEmpty(childOrgBusinessId)) { if (!currentOrgIdList.containsAll(childOrgBusinessId)) { model.setErrorMsg("|该党组织下存在下级组织或党员数据"); this.clear(model); failResultList.add(model); errorFlag=true; } } if(StringUtils.isBlank(model.getErrorMsg())){ PartyUserCriteriapartyUserCriteria=newPartyUserCriteria(); partyUserCriteria.setPid(model.getOrgBusinessId()); longuserCount=partyUserService.countPartyUser(partyUserCriteria); if(userCount>0){ model.setErrorMsg("|该党组织下存在下级组织或党员数据"); this.clear(model); failResultList.add(model); errorFlag=true; } } } } else { model.setErrorMsg("|党组织全称或上级上组织全称错误"); this.clear(model); failResultList.add(model); errorFlag=true; } } if (errorFlag) { List<OrgBatchUpdateExcelModel>successList=successResultList.stream().filter(e->StringUtils.isBlank(e.getErrorMsg())).collect(Collectors.toList()); successResultList=newArrayList<>(); if (!CollectionUtils.isEmpty(successList)) { successResultList.addAll(successList); } } } } /*** 清楚不需要字段** @param model*/privatevoidclear(OrgBatchUpdateExcelModelmodel) { model.setPartyTypeSimple(null); model.setPartyType(null); model.setDeleteFlag(null); model.setXzqh(null); model.setPartyCompanyIntro(null); model.setCompanyType(null); model.setOrgBusinessId(null); model.setCompanyBusinessId(null); } publicvoidonException(Exceptionexception, AnalysisContextcontext) { task.setTaskEnd(newDate()); task.setTaskStatus(EnumTaskStatus.FAIL); task.setTaskErrorInfo(exception.getMessage()); taskService.updateStatusById(task); } publicList<OrgBatchUpdateExcelModel>getSuccessResultList() { returnsuccessResultList; } publicList<OrgBatchUpdateExcelModel>getFailResultList() { returnfailResultList; }
7.插入成功数据,上传失败数据到OSS供前端下载
/*** 导入文件-批量修改党组织** @param operator 操作人* @param tenantCode 租户* @param originalFilename 文件名* @param task 任务* @param successList 成功的数据* @param failList 失败的数据*/rollbackFor=Exception.class) (publicvoidbatchUpdateImportOrg(Stringoperator, StringtenantCode, StringoriginalFilename, ObExcelScheduleTasktask, List<OrgBatchUpdateExcelModel>successList, List<OrgBatchUpdateExcelModel>failList) { task.setTaskStatus(EnumTaskStatus.DONE); // 修改数据if (!CollectionUtils.isEmpty(successList)) { try { obPartyOrgMapper.updateBatchForImportOrg(successList, operator, tenantCode); List<String>orgBusinessIdList=successList.stream().filter(e->OrgConst.YES_STATE.equals(e.getDeleteFlag())).map(e->e.getOrgBusinessId()).collect(Collectors.toList()); if(!CollectionUtils.isEmpty(orgBusinessIdList)){ obOrgMapper.batchDeleteObOrg(orgBusinessIdList, operator, newDate(), tenantCode); } } catch (Exceptione) { task.setTaskStatus(EnumTaskStatus.FAIL); task.setTaskErrorInfo(CommonUtil.stringAppend("生成和上传党组织批量修改错误文件时异常 errorId=", ErrorIdUtil.getErrorId(), " error=", ExceptionUtil.stacktraceToString(e, 150))); } } // 上传错误数据文件到ossif (!CollectionUtils.isEmpty(failList)) { InputStreamossInputStream=null; try (ByteArrayOutputStreamoutputStream=newByteArrayOutputStream()) { EasyExcel.write(outputStream, OrgBatchUpdateExcelVO.class).sheet(OrgConst.BATCH_UPDATE_EXCEL_SHEET).doWrite(failList); ossInputStream=newByteArrayInputStream(outputStream.toByteArray()); //上传文件FileUploadResultresult=fileStorageService.uploadFile(ossInputStream, UploadResourceType.EXCEL, System.currentTimeMillis() +originalFilename); if (result!=null) { task.setTaskStatus(EnumTaskStatus.FAIL); task.setOssFileUrl(result.getUrl()); task.setOssFileStatus(EnumOssFileStatus.NORMAL); } } catch (Exceptione) { task.setTaskErrorInfo(CommonUtil.stringAppend("生成和上传党组织批量修改错误文件时异常 errorId=", ErrorIdUtil.getErrorId(), " error=", ExceptionUtil.stacktraceToString(e, 150))); } } task.setTaskEnd(newDate()); taskService.updateStatusById(task); }