From 010201912ec89d3911d6c40437a3c9e59c78028a Mon Sep 17 00:00:00 2001 From: CMM <2198256324@qq.com> Date: Thu, 17 Aug 2023 17:25:10 +0800 Subject: [PATCH] =?UTF-8?q?=E7=BB=A9=E6=95=88=E8=AF=84=E4=BB=B7-=E5=8D=95?= =?UTF-8?q?=E4=BD=8D=E8=87=AA=E8=AF=84=E8=AF=84=E5=88=86=E6=98=8E=E7=BB=86?= =?UTF-8?q?=E5=AF=BC=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/ReAppraisalController.java | 10 + .../performance/manage/OrgSelfAppraisalManage.java | 19 +- .../manage/PerformanceAppraisalPlanManage.java | 51 +++-- .../performance/manage/ReAppraisalManage.java | 209 +++++++++++++++++++++ .../model/dto/AppraisalScoreExportDTO.java | 60 ------ .../model/dto/ReAppraisalScoreExportDTO.java | 69 +++++++ .../model/dto/SelfAppraisalScoreExportDTO.java | 60 ++++++ .../model/req/PerformanceAppraisalExportReq.java | 2 + .../util/ExcelFillCellMergeStrategy.java | 102 ++++++++++ .../performance/util/MultiColumnMergeStrategy.java | 109 +++++++++++ 10 files changed, 610 insertions(+), 81 deletions(-) delete mode 100644 pmapi/src/main/java/com/ningdatech/pmapi/performance/model/dto/AppraisalScoreExportDTO.java create mode 100644 pmapi/src/main/java/com/ningdatech/pmapi/performance/model/dto/ReAppraisalScoreExportDTO.java create mode 100644 pmapi/src/main/java/com/ningdatech/pmapi/performance/model/dto/SelfAppraisalScoreExportDTO.java create mode 100644 pmapi/src/main/java/com/ningdatech/pmapi/performance/util/ExcelFillCellMergeStrategy.java create mode 100644 pmapi/src/main/java/com/ningdatech/pmapi/performance/util/MultiColumnMergeStrategy.java diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/performance/controller/ReAppraisalController.java b/pmapi/src/main/java/com/ningdatech/pmapi/performance/controller/ReAppraisalController.java index a3c61f4..0e93a2e 100644 --- a/pmapi/src/main/java/com/ningdatech/pmapi/performance/controller/ReAppraisalController.java +++ b/pmapi/src/main/java/com/ningdatech/pmapi/performance/controller/ReAppraisalController.java @@ -1,9 +1,12 @@ package com.ningdatech.pmapi.performance.controller; +import javax.servlet.http.HttpServletResponse; import javax.validation.Valid; import com.ningdatech.log.annotation.WebLog; +import com.ningdatech.pmapi.common.util.ExcelDownUtil; import com.ningdatech.pmapi.performance.manage.ReAppraisalManage; +import com.ningdatech.pmapi.performance.model.req.PerformanceAppraisalExportReq; import org.springframework.web.bind.annotation.*; import com.ningdatech.basic.model.PageVo; @@ -50,4 +53,11 @@ public class ReAppraisalController { return reAppraisalManage.submitReAppraisal(param); } + @GetMapping("/score/export") + @ApiOperation("复评打分导出") + @WebLog(value = "复评打分导出",modular = "绩效评价-人工复评") + public void exportScore(@Valid @ModelAttribute PerformanceAppraisalExportReq param, HttpServletResponse response){ + ExcelDownUtil.downXls(response, param, reAppraisalManage::exportScore); + } + } diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/performance/manage/OrgSelfAppraisalManage.java b/pmapi/src/main/java/com/ningdatech/pmapi/performance/manage/OrgSelfAppraisalManage.java index 274303a..cd080f8 100644 --- a/pmapi/src/main/java/com/ningdatech/pmapi/performance/manage/OrgSelfAppraisalManage.java +++ b/pmapi/src/main/java/com/ningdatech/pmapi/performance/manage/OrgSelfAppraisalManage.java @@ -16,9 +16,8 @@ import com.ningdatech.pmapi.common.util.ExcelDownUtil; import com.ningdatech.pmapi.common.util.ExcelExportStyle; import com.ningdatech.pmapi.performance.constant.BizConst; import com.ningdatech.pmapi.performance.enumration.AppraisalTypeEnum; -import com.ningdatech.pmapi.performance.enumration.PerformanceTemplateTypeEnum; import com.ningdatech.pmapi.performance.helper.TemplateDetailBuildHelper; -import com.ningdatech.pmapi.performance.model.dto.AppraisalScoreExportDTO; +import com.ningdatech.pmapi.performance.model.dto.SelfAppraisalScoreExportDTO; import com.ningdatech.pmapi.performance.model.dto.ProjectAppraisalDTO; import com.ningdatech.pmapi.performance.model.dto.ProjectAppraisalInfoDTO; import com.ningdatech.pmapi.performance.model.entity.*; @@ -26,12 +25,13 @@ import com.ningdatech.pmapi.performance.model.req.PerformanceAppraisalExportReq; import com.ningdatech.pmapi.performance.model.req.PerformanceAppraisalListReq; import com.ningdatech.pmapi.performance.model.vo.*; import com.ningdatech.pmapi.performance.service.*; +import com.ningdatech.pmapi.performance.util.ExcelFillCellMergeStrategy; +import com.ningdatech.pmapi.performance.util.MultiColumnMergeStrategy; import com.ningdatech.pmapi.portrait.model.entity.ProjectTag; import com.ningdatech.pmapi.portrait.service.IProjectTagService; import com.ningdatech.pmapi.projectlib.enumeration.ProjectStatusEnum; import com.ningdatech.pmapi.projectlib.enumeration.ProjectTypeEnum; import com.ningdatech.pmapi.projectlib.model.entity.Project; -import com.ningdatech.pmapi.projectlib.service.IProjectApplicationService; import com.ningdatech.pmapi.projectlib.service.IProjectService; import com.ningdatech.pmapi.sys.model.entity.Role; import com.ningdatech.pmapi.sys.service.IRoleService; @@ -432,8 +432,8 @@ public class OrgSelfAppraisalManage { .eq(PerformanceIndicatorProjectTemplateDetail::getTemplateId, projectTemplate.getId())); Map templateDetailMap = templateDetails.stream().collect(Collectors.toMap(PerformanceIndicatorProjectTemplateDetail::getId, t -> t)); - List exportDataList = Lists.newArrayList(); - List exportAdditionalDataList = Lists.newArrayList(); + List exportDataList = Lists.newArrayList(); + List exportAdditionalDataList = Lists.newArrayList(); // 构建指标和打分详情 List scoreInfoList = performanceAppraisalScoreInfoService.list(Wrappers.lambdaQuery(PerformanceAppraisalScoreInfo.class) .eq(PerformanceAppraisalScoreInfo::getAppraisalId, appraisalId) @@ -445,7 +445,7 @@ public class OrgSelfAppraisalManage { // 筛选出所有打分的三级指标模板详情ID for (PerformanceAppraisalScoreInfo scoreInfo : scoreInfoList) { - AppraisalScoreExportDTO thirdDto = new AppraisalScoreExportDTO(); + SelfAppraisalScoreExportDTO thirdDto = new SelfAppraisalScoreExportDTO(); Long detailId = scoreInfo.getTemplateDetailId(); PerformanceIndicatorProjectTemplateDetail thirdTemplateDetail = templateDetailMap.get(detailId); thirdDto.setThirdIndexName(thirdTemplateDetail.getName()); @@ -489,10 +489,15 @@ public class OrgSelfAppraisalManage { String fileName = "绩效评价_单位自评_评分明细表"; ExcelDownUtil.setFileName(fileName, response); + int[] mergeColumnIndex = {0}; + // 需要从第几行开始合并 + int mergeRowIndex = 1; //数据导出处理函数 try { - EasyExcel.write(response.getOutputStream(), AppraisalScoreExportDTO.class) + EasyExcel.write(response.getOutputStream(), SelfAppraisalScoreExportDTO.class) .autoCloseStream(false) + .registerWriteHandler(new MultiColumnMergeStrategy(exportDataList.size(),0,1)) + .registerWriteHandler(new ExcelFillCellMergeStrategy(mergeRowIndex,mergeColumnIndex)) .registerWriteHandler(ExcelExportStyle.formalStyle()) .sheet(fileName) .doWrite(exportDataList); diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/performance/manage/PerformanceAppraisalPlanManage.java b/pmapi/src/main/java/com/ningdatech/pmapi/performance/manage/PerformanceAppraisalPlanManage.java index 51facf2..760631c 100644 --- a/pmapi/src/main/java/com/ningdatech/pmapi/performance/manage/PerformanceAppraisalPlanManage.java +++ b/pmapi/src/main/java/com/ningdatech/pmapi/performance/manage/PerformanceAppraisalPlanManage.java @@ -498,27 +498,50 @@ public class PerformanceAppraisalPlanManage { PerformanceAppraisal pa = performanceAppraisalService.getById(id); VUtils.isTrue(Objects.isNull(pa)).throwMessage("绩效评价不存在 删除失败!"); + // 获取评价计划内的待评价项目信息,并按自评开始时间排序 + List paps = performanceAppraisalProjectService.list(Wrappers.lambdaQuery(PerformanceAppraisalProject.class) + .eq(PerformanceAppraisalProject::getAppraisalId, id) + .orderBy(Boolean.TRUE,Boolean.TRUE,PerformanceAppraisalProject::getSelfAppraisalStart)); + // 获取计划内项目的自评开始时间 + Optional min = paps.stream().map(PerformanceAppraisalProject::getSelfAppraisalStart).min(LocalDateTime::compareTo); + if (min.isPresent()){ + // 比较当前时间与自评开始时间最小值 + if (LocalDateTime.now().isAfter(min.get())){ + throw new BizException("评价计划内已有项目到达自评时间,无法删除!"); + } + } + if(performanceAppraisalService.removeById(id)){ // 删除评价计划关联的项目 //绩效关联的项目 - List paps = performanceAppraisalProjectService.list(Wrappers.lambdaQuery(PerformanceAppraisalProject.class) - .eq(PerformanceAppraisalProject::getAppraisalId, id)); - performanceAppraisalProjectService.removeBatchByIds(paps); - List projectCodes = paps.stream().map(PerformanceAppraisalProject::getProjectCode).collect(Collectors.toList()); - // 删除项目的打分信息 - performanceAppraisalScoreInfoService.remove(Wrappers.lambdaQuery(PerformanceAppraisalScoreInfo.class) - .eq(PerformanceAppraisalScoreInfo::getAppraisalId,id) - .in(PerformanceAppraisalScoreInfo::getAppraisalProjectCode,projectCodes)); + if (CollUtil.isNotEmpty(paps)) { + performanceAppraisalProjectService.removeBatchByIds(paps); + List projectCodes = paps.stream().map(PerformanceAppraisalProject::getProjectCode).collect(Collectors.toList()); + // 删除项目的打分信息 + List scoreInfos = performanceAppraisalScoreInfoService.list(Wrappers.lambdaQuery(PerformanceAppraisalScoreInfo.class) + .eq(PerformanceAppraisalScoreInfo::getAppraisalId, id) + .in(PerformanceAppraisalScoreInfo::getAppraisalProjectCode, projectCodes)); + if (CollUtil.isNotEmpty(scoreInfos)) { + performanceAppraisalScoreInfoService.removeBatchByIds(scoreInfos); + } + + } // 删除评价计划关联的应用 //绩效关联的应用 List paas = performanceAppraisalApplicationService.list(Wrappers.lambdaQuery(PerformanceAppraisalApplication.class) .eq(PerformanceAppraisalApplication::getAppraisalId, id)); - performanceAppraisalApplicationService.removeBatchByIds(paas); - List applicationIds = paas.stream().map(PerformanceAppraisalApplication::getApplicationId).collect(Collectors.toList()); - // 删除应用的打分信息 - performanceAppraisalAppScoreInfoService.remove(Wrappers.lambdaQuery(PerformanceAppraisalAppScoreInfo.class) - .eq(PerformanceAppraisalAppScoreInfo::getAppraisalId,id) - .in(PerformanceAppraisalAppScoreInfo::getApplicationId,applicationIds)); + if (CollUtil.isNotEmpty(paas)) { + performanceAppraisalApplicationService.removeBatchByIds(paas); + List applicationIds = paas.stream().map(PerformanceAppraisalApplication::getApplicationId).collect(Collectors.toList()); + // 删除应用的打分信息 + List scoreInfos = performanceAppraisalAppScoreInfoService + .list(Wrappers.lambdaQuery(PerformanceAppraisalAppScoreInfo.class) + .eq(PerformanceAppraisalAppScoreInfo::getAppraisalId, id) + .in(PerformanceAppraisalAppScoreInfo::getApplicationId, applicationIds)); + if (CollUtil.isNotEmpty(scoreInfos)) { + performanceAppraisalAppScoreInfoService.removeBatchByIds(scoreInfos); + } + } // 删除评级计划关联的分组信息 groupService.remove(Wrappers.lambdaQuery(PerformanceAppraisalProjectGroup.class) .eq(PerformanceAppraisalProjectGroup::getAppraisalId,id)); diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/performance/manage/ReAppraisalManage.java b/pmapi/src/main/java/com/ningdatech/pmapi/performance/manage/ReAppraisalManage.java index 58a8304..f3dea12 100644 --- a/pmapi/src/main/java/com/ningdatech/pmapi/performance/manage/ReAppraisalManage.java +++ b/pmapi/src/main/java/com/ningdatech/pmapi/performance/manage/ReAppraisalManage.java @@ -1,12 +1,25 @@ package com.ningdatech.pmapi.performance.manage; +import java.io.IOException; import java.math.BigDecimal; import java.time.LocalDateTime; import java.util.*; import java.util.stream.Collectors; +import com.alibaba.excel.EasyExcel; import com.google.common.collect.Lists; +import com.ningdatech.pmapi.common.enumeration.CommonEnum; +import com.ningdatech.pmapi.common.util.ExcelDownUtil; +import com.ningdatech.pmapi.common.util.ExcelExportStyle; +import com.ningdatech.pmapi.performance.model.dto.ReAppraisalScoreExportDTO; +import com.ningdatech.pmapi.performance.model.dto.SelfAppraisalScoreExportDTO; +import com.ningdatech.pmapi.performance.model.req.PerformanceAppraisalExportReq; +import com.ningdatech.pmapi.performance.util.ExcelFillCellMergeStrategy; +import com.ningdatech.pmapi.performance.util.MultiColumnMergeStrategy; +import com.ningdatech.pmapi.portrait.model.entity.ProjectTag; +import com.ningdatech.pmapi.portrait.service.IProjectTagService; import org.apache.commons.lang3.StringUtils; +import org.checkerframework.checker.nullness.qual.Nullable; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; @@ -39,6 +52,8 @@ import cn.hutool.core.collection.CollUtil; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; +import javax.servlet.http.HttpServletResponse; + /** * ReAppraisalManage * @return @@ -57,6 +72,8 @@ public class ReAppraisalManage { private final IPerformanceIndicatorProjectTemplateDetailService indicatorProjectTemplateDetailService; private final IPerformanceAppraisalScoreInfoService performanceAppraisalScoreInfoService; private final IPerformanceAppraisalProjectGroupService groupService; + private final IProjectTagService projectTagService; + private final IPerformanceIndicatorProjectTemplateService indicatorProjectTemplateService; /** * 复评-评价计划列表 * @param req @@ -314,4 +331,196 @@ public class ReAppraisalManage { } } } + + public void exportScore(HttpServletResponse response, PerformanceAppraisalExportReq param) { + UserInfoDetails user = LoginUserUtil.loginUserDetail(); + String regionCode = user.getRegionCode(); + String projectCode = param.getProjectCode(); + Long appraisalId = param.getAppraisalId(); + + // 根据项目编码获取最新版本的项目信息 + Project project = projectService.getProjectByCode(projectCode); + VUtils.isTrue(Objects.isNull(project)).throwMessage("项目不存在!"); + // 根据项目类型、预算年度、批复金额、项目标签匹配本区域指标模版 + Integer projectType = project.getProjectType(); + Integer projectYear = project.getProjectYear(); + BigDecimal approvalAmount = project.getApprovalAmount(); + VUtils.isTrue(Objects.isNull(approvalAmount)).throwMessage("未获取到该项目的立项批复金额"); + // 根据项目code获取项目标签ID列表 + List tagIdList = projectTagService.list(Wrappers.lambdaQuery(ProjectTag.class) + .eq(ProjectTag::getProjectCode, projectCode)).stream() + .map(ProjectTag::getTagId).collect(Collectors.toList()); + VUtils.isTrue(CollUtil.isEmpty(tagIdList)).throwMessage("当前项目未设置标签,匹配不到指标模板,请至项目库或评价计划编辑页面设置标签!"); + + List strIdList = tagIdList.stream().map(String::valueOf).collect(Collectors.toList()); + String projectTagIds = String.join(StrPool.COMMA, strIdList); + + Integer amountRange = null; + if (approvalAmount.compareTo(BigDecimal.valueOf(BizConst.FIVE_MILLION)) < 0){ + amountRange = BizConst.AMOUNT_RANGE_ONE; + } else if (approvalAmount.compareTo(BigDecimal.valueOf(BizConst.FIVE_MILLION)) >= 0 && + approvalAmount.compareTo(BigDecimal.valueOf(BizConst.TWENTY_MILLION)) < 0) { + amountRange = BizConst.AMOUNT_RANGE_TWO; + }else if (approvalAmount.compareTo(BigDecimal.valueOf(BizConst.TWENTY_MILLION)) >= 0){ + amountRange = BizConst.AMOUNT_RANGE_THREE; + } + LambdaQueryWrapper wrapper = Wrappers.lambdaQuery(PerformanceIndicatorProjectTemplate.class) + .eq(PerformanceIndicatorProjectTemplate::getRegionCode, regionCode) + .eq(PerformanceIndicatorProjectTemplate::getProjectType, projectType) + .eq(PerformanceIndicatorProjectTemplate::getProjectYear, projectYear) + .eq(PerformanceIndicatorProjectTemplate::getAmountRange, amountRange) + .eq(PerformanceIndicatorProjectTemplate::getProjectTagIds,projectTagIds) + .eq(PerformanceIndicatorProjectTemplate::getStatus, CommonEnum.YES.getCode()) + .orderByDesc(PerformanceIndicatorProjectTemplate::getUpdateOn); + List templates = indicatorProjectTemplateService.list(wrapper); + VUtils.isTrue(CollUtil.isEmpty(templates)).throwMessage("该项目匹配不到指标模板,请返回上一页或者刷新重试。"); + if (templates.size() > 1){ + throw new BizException("当前项目匹配到多个模板,请返回模板库检查模板配置!"); + } + PerformanceIndicatorProjectTemplate projectTemplate = templates.get(0); + // 装配项目指标详情及分数信息 + // 获取模版绩效指标详情 + List templateDetails = indicatorProjectTemplateDetailService.list(Wrappers.lambdaQuery(PerformanceIndicatorProjectTemplateDetail.class) + .eq(PerformanceIndicatorProjectTemplateDetail::getTemplateId, projectTemplate.getId())); + Map templateDetailMap = templateDetails.stream().collect(Collectors.toMap(PerformanceIndicatorProjectTemplateDetail::getId, t -> t)); + + List exportDataList = Lists.newArrayList(); + List exportAdditionalDataList = Lists.newArrayList(); + // 构建指标和打分详情 + List scoreInfoList = performanceAppraisalScoreInfoService.list(Wrappers.lambdaQuery(PerformanceAppraisalScoreInfo.class) + .eq(PerformanceAppraisalScoreInfo::getAppraisalId, appraisalId) + .eq(PerformanceAppraisalScoreInfo::getAppraisalType, AppraisalTypeEnum.RE_APPRAISAL.getCode()) + .eq(PerformanceAppraisalScoreInfo::getAppraisalProjectCode, projectCode) + .orderBy(Boolean.TRUE, Boolean.TRUE, PerformanceAppraisalScoreInfo::getTemplateDetailId)); + Map scoreInfoMap = scoreInfoList.stream() + .collect(Collectors.toMap(PerformanceAppraisalScoreInfo::getTemplateDetailId, p -> p)); + // 按照复评打分人员分组 + Map> scoreInfoUserMap = scoreInfoList.stream() + .collect(Collectors.groupingBy(PerformanceAppraisalScoreInfo::getAppraisalEmployeeName)); + Set reUserList = scoreInfoUserMap.keySet(); + + // 筛选出所有打分的三级指标模板详情ID + for (PerformanceAppraisalScoreInfo scoreInfo : scoreInfoList) { + SelfAppraisalScoreExportDTO thirdDto = new SelfAppraisalScoreExportDTO(); + Long detailId = scoreInfo.getTemplateDetailId(); + PerformanceIndicatorProjectTemplateDetail thirdTemplateDetail = templateDetailMap.get(detailId); + thirdDto.setThirdIndexName(thirdTemplateDetail.getName()); + thirdDto.setIndexDetail(thirdTemplateDetail.getIndexDetail()); + thirdDto.setGradeDetail(thirdTemplateDetail.getGradeDetail()); + thirdDto.setSupportMaterial(thirdTemplateDetail.getSupportMaterial()); + thirdDto.setIndexScore(thirdTemplateDetail.getIndexScore()); + if (Boolean.TRUE.equals(thirdTemplateDetail.getIsAdditional())) { + thirdDto.setIsAdditional(CommonEnum.YES.getDesc()); + } else if (Boolean.FALSE.equals(thirdTemplateDetail.getIsAdditional())) { + thirdDto.setIsAdditional(CommonEnum.NO.getDesc()); + } + PerformanceAppraisalScoreInfo appraisalScoreInfo = scoreInfoMap.get(thirdTemplateDetail.getId()); + if (Objects.nonNull(appraisalScoreInfo)) { + thirdDto.setAppraisalBasis(appraisalScoreInfo.getAppraisalBasis()); + thirdDto.setAppraisalScore(appraisalScoreInfo.getAppraisalScore()); + } + // 二级指标名称 + Long secondId = thirdTemplateDetail.getParentId(); + if (Objects.nonNull(secondId)) { + PerformanceIndicatorProjectTemplateDetail secondTemplateDetail = templateDetailMap.get(secondId); + if (Objects.nonNull(secondTemplateDetail)) { + thirdDto.setSecondIndexName(secondTemplateDetail.getName()); + // 一级指标名称 + Long firstId = secondTemplateDetail.getParentId(); + if (Objects.nonNull(firstId)){ + PerformanceIndicatorProjectTemplateDetail firstTemplateDetail = templateDetailMap.get(firstId); + if (Objects.nonNull(firstTemplateDetail)) { + thirdDto.setFirstIndexName(firstTemplateDetail.getName()); + } + } + } + } + if (Boolean.FALSE.equals(thirdTemplateDetail.getIsAdditional())) { + exportDataList.add(thirdDto); + }else { + exportAdditionalDataList.add(thirdDto); + } + } + exportDataList.addAll(exportAdditionalDataList); + List> dataList = Lists.newArrayList(); + dataList.add(exportDataList); + String fileName = "绩效评价_人工复评_评分明细表"; + ExcelDownUtil.setFileName(fileName, response); + int[] mergeColumnIndex = {0}; + // 需要从第几行开始合并 + int mergeRowIndex = 2; + + //数据导出处理函数 + try { + EasyExcel.write(response.getOutputStream(), SelfAppraisalScoreExportDTO.class) + .autoCloseStream(false) + .head(head(reUserList)) + .registerWriteHandler(new MultiColumnMergeStrategy(exportDataList.size(),0,1)) + .registerWriteHandler(new ExcelFillCellMergeStrategy(mergeRowIndex,mergeColumnIndex)) + .registerWriteHandler(ExcelExportStyle.formalStyle()) + .sheet(fileName) + //.doWrite(dataList); + .doWrite(getData()); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + private List> head(Set reUserList) { + List> list = Lists.newArrayList(); + List head0 = Lists.newArrayList(); + head0.add("一级指标"); + List head1 = Lists.newArrayList(); + head1.add("二级指标"); + List head2 = Lists.newArrayList(); + head2.add("三级指标"); + List head3 = Lists.newArrayList(); + head2.add("指标分值"); + List head4 = Lists.newArrayList(); + head2.add("指标细则"); + List head5 = Lists.newArrayList(); + head2.add("评分细则"); + List head6 = Lists.newArrayList(); + head2.add("佐证材料"); + List head7 = Lists.newArrayList(); + head2.add("自评依据"); + List head8 = Lists.newArrayList(); + head2.add("自评得分"); + + + list.add(head0); + list.add(head1); + list.add(head2); + list.add(head3); + list.add(head4); + list.add(head5); + list.add(head6); + list.add(head7); + list.add(head8); + + List reUserHead = Lists.newArrayList(); + reUserHead.add("复评依据"); + reUserHead.add("复评得分"); + + for (String reUser : reUserList) { + for (String h : reUserHead) { + List reUsers = Lists.newArrayList(); + reUsers.add(reUser + "(复评)"); + reUsers.add(h); + list.add(reUsers); + } + } + return list; + } + + public List> getData() { + List> total = new ArrayList<>(); + List list = new ArrayList<>(); + for (int i = 0; i < 15; i++) { + ReAppraisalScoreExportDTO dto = new ReAppraisalScoreExportDTO(); + dto.setFirstIndexName("一级指标" + i); + list.add(dto); + } + total.add(list); + return total; + } } diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/performance/model/dto/AppraisalScoreExportDTO.java b/pmapi/src/main/java/com/ningdatech/pmapi/performance/model/dto/AppraisalScoreExportDTO.java deleted file mode 100644 index 84132dd..0000000 --- a/pmapi/src/main/java/com/ningdatech/pmapi/performance/model/dto/AppraisalScoreExportDTO.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.ningdatech.pmapi.performance.model.dto; - -import java.io.Serializable; -import java.math.BigDecimal; - -import com.alibaba.excel.annotation.ExcelProperty; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; - -/** - * 绩效打分详情导出实体 - * - * @author CMM - * @since 2023/08/16 10:31 - */ -@Data -public class AppraisalScoreExportDTO implements Serializable { - - private static final long serialVersionUID = 1L; - - @ApiModelProperty("一级指标名称") - @ExcelProperty(value = "一级指标",index = 0) - private String firstIndexName; - - @ApiModelProperty("二级指标名称") - @ExcelProperty(value = "二级指标",index = 1) - private String secondIndexName; - - @ApiModelProperty("三级指标名称") - @ExcelProperty(value = "三级指标",index = 2) - private String thirdIndexName; - - @ApiModelProperty("指标分值 3级指标才有") - @ExcelProperty(value = "指标分值",index = 3) - private BigDecimal indexScore; - - @ApiModelProperty("指标细则 3级指标才有") - @ExcelProperty(value = "指标细则",index = 4) - private String indexDetail; - - @ApiModelProperty("评分细则") - @ExcelProperty(value = "评分细则",index = 5) - private String gradeDetail; - - @ApiModelProperty("佐证材料描述") - @ExcelProperty(value = "佐证材料",index = 6) - private String supportMaterial; - - @ApiModelProperty("自评依据") - @ExcelProperty(value = "自评依据",index = 7) - private String appraisalBasis; - - @ApiModelProperty("自评得分") - @ExcelProperty(value = "自评得分",index = 8) - private BigDecimal appraisalScore; - - @ApiModelProperty("是否为附加指标") - @ExcelProperty(value = "是否附加指标",index = 9) - private String isAdditional; -} diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/performance/model/dto/ReAppraisalScoreExportDTO.java b/pmapi/src/main/java/com/ningdatech/pmapi/performance/model/dto/ReAppraisalScoreExportDTO.java new file mode 100644 index 0000000..22d78e4 --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/performance/model/dto/ReAppraisalScoreExportDTO.java @@ -0,0 +1,69 @@ +package com.ningdatech.pmapi.performance.model.dto; + +import java.io.Serializable; +import java.math.BigDecimal; + +import com.alibaba.excel.annotation.ExcelProperty; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 绩效打分详情导出实体 + * + * @author CMM + * @since 2023/08/16 10:31 + */ +@Data +public class ReAppraisalScoreExportDTO implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("一级指标名称") + @ExcelProperty(value = "一级指标",index = 0) + private String firstIndexName; + + @ApiModelProperty("二级指标名称") + @ExcelProperty(value = "二级指标",index = 1) + private String secondIndexName; + + @ApiModelProperty("三级指标名称") + @ExcelProperty(value = "三级指标",index = 2) + private String thirdIndexName; + + @ApiModelProperty("指标分值 3级指标才有") + @ExcelProperty(value = "指标分值",index = 3) + private BigDecimal indexScore; + + @ApiModelProperty("指标细则 3级指标才有") + @ExcelProperty(value = "指标细则",index = 4) + private String indexDetail; + + @ApiModelProperty("评分细则") + @ExcelProperty(value = "评分细则",index = 5) + private String gradeDetail; + + @ApiModelProperty("佐证材料描述") + @ExcelProperty(value = "佐证材料",index = 6) + private String supportMaterial; + + @ApiModelProperty("自评依据") + @ExcelProperty(value = "自评依据",index = 7) + private String selfAppraisalBasis; + + @ApiModelProperty("自评得分") + @ExcelProperty(value = "自评得分",index = 8) + private BigDecimal selfAppraisalScore; + + @ApiModelProperty("复评依据") + @ExcelProperty(value = "复评依据",index = 9) + private String reAppraisalBasis; + + @ApiModelProperty("复评得分") + @ExcelProperty(value = "复评得分",index = 10) + private BigDecimal reAppraisalScore; + + @ApiModelProperty("是否为附加指标") + @ExcelProperty(value = "是否附加指标",index = 11) + private String isAdditional; +} diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/performance/model/dto/SelfAppraisalScoreExportDTO.java b/pmapi/src/main/java/com/ningdatech/pmapi/performance/model/dto/SelfAppraisalScoreExportDTO.java new file mode 100644 index 0000000..4e0cd75 --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/performance/model/dto/SelfAppraisalScoreExportDTO.java @@ -0,0 +1,60 @@ +package com.ningdatech.pmapi.performance.model.dto; + +import java.io.Serializable; +import java.math.BigDecimal; + +import com.alibaba.excel.annotation.ExcelProperty; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 绩效打分详情导出实体 + * + * @author CMM + * @since 2023/08/16 10:31 + */ +@Data +public class SelfAppraisalScoreExportDTO implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("一级指标名称") + @ExcelProperty(value = "一级指标",index = 0) + private String firstIndexName; + + @ApiModelProperty("二级指标名称") + @ExcelProperty(value = "二级指标",index = 1) + private String secondIndexName; + + @ApiModelProperty("三级指标名称") + @ExcelProperty(value = "三级指标",index = 2) + private String thirdIndexName; + + @ApiModelProperty("指标分值 3级指标才有") + @ExcelProperty(value = "指标分值",index = 3) + private BigDecimal indexScore; + + @ApiModelProperty("指标细则 3级指标才有") + @ExcelProperty(value = "指标细则",index = 4) + private String indexDetail; + + @ApiModelProperty("评分细则") + @ExcelProperty(value = "评分细则",index = 5) + private String gradeDetail; + + @ApiModelProperty("佐证材料描述") + @ExcelProperty(value = "佐证材料",index = 6) + private String supportMaterial; + + @ApiModelProperty("自评依据") + @ExcelProperty(value = "自评依据",index = 7) + private String appraisalBasis; + + @ApiModelProperty("自评得分") + @ExcelProperty(value = "自评得分",index = 8) + private BigDecimal appraisalScore; + + @ApiModelProperty("是否为附加指标") + @ExcelProperty(value = "是否附加指标",index = 9) + private String isAdditional; +} diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/performance/model/req/PerformanceAppraisalExportReq.java b/pmapi/src/main/java/com/ningdatech/pmapi/performance/model/req/PerformanceAppraisalExportReq.java index 7163acb..004729f 100644 --- a/pmapi/src/main/java/com/ningdatech/pmapi/performance/model/req/PerformanceAppraisalExportReq.java +++ b/pmapi/src/main/java/com/ningdatech/pmapi/performance/model/req/PerformanceAppraisalExportReq.java @@ -17,4 +17,6 @@ public class PerformanceAppraisalExportReq { @ApiModelProperty("评价计划Id") private Long appraisalId; + + } diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/performance/util/ExcelFillCellMergeStrategy.java b/pmapi/src/main/java/com/ningdatech/pmapi/performance/util/ExcelFillCellMergeStrategy.java new file mode 100644 index 0000000..431cafa --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/performance/util/ExcelFillCellMergeStrategy.java @@ -0,0 +1,102 @@ +package com.ningdatech.pmapi.performance.util; + +import com.alibaba.excel.metadata.Head; +import com.alibaba.excel.metadata.data.WriteCellData; +import com.alibaba.excel.write.handler.CellWriteHandler; +import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; +import com.alibaba.excel.write.metadata.holder.WriteTableHolder; +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.CellType; +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.ss.usermodel.Sheet; +import org.apache.poi.ss.util.CellRangeAddress; + +import java.util.List; + +/** + * 单元格合并策略 + * + * @author CMM + * @since 2023/08/17 10:57 + */ + +public class ExcelFillCellMergeStrategy implements CellWriteHandler { + + private int[] mergeColumnIndex; + private int mergeRowIndex; + + public ExcelFillCellMergeStrategy() { + } + + public ExcelFillCellMergeStrategy(int mergeRowIndex, int[] mergeColumnIndex) { + this.mergeRowIndex = mergeRowIndex; + this.mergeColumnIndex = mergeColumnIndex; + } + + + @Override + public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, List> list, Cell cell, Head head, Integer integer, Boolean aBoolean) { + //当前行 + int curRowIndex = cell.getRowIndex(); + //当前列 + int curColIndex = cell.getColumnIndex(); + + if (curRowIndex > mergeRowIndex) { + for (int columnIndex : mergeColumnIndex) { + if (curColIndex == columnIndex) { + mergeWithPrevRow(writeSheetHolder, cell, curRowIndex, curColIndex); + break; + } + } + } + } + + + + /** + * 当前单元格向上合并 + * + * @param cell 当前单元格 + * @param curRowIndex 当前行 + * @param curColIndex 当前列 + */ + private void mergeWithPrevRow(WriteSheetHolder writeSheetHolder, Cell cell, int curRowIndex, int curColIndex) { + //获取当前行的当前列的数据和上一行的当前列列数据,通过上一行数据是否相同进行合并 + Object curData = cell.getCellType() == CellType.STRING ? cell.getStringCellValue() : cell.getNumericCellValue(); + Cell preCell = cell.getSheet().getRow(curRowIndex - 1).getCell(curColIndex); + Object preData = preCell.getCellType() == CellType.STRING ? preCell.getStringCellValue() : preCell.getNumericCellValue(); + + // 比较当前行的第一列的单元格与上一行是否相同,相同合并当前单元格与上一行 + if (curData.equals(preData)) { + Sheet sheet = writeSheetHolder.getSheet(); + List mergeRegions = sheet.getMergedRegions(); + boolean isMerged = false; + for (int i = 0; i < mergeRegions.size() && !isMerged; i++) { + CellRangeAddress cellRangeAddr = mergeRegions.get(i); + // 若上一个单元格已经被合并,则先移出原有的合并单元,再重新添加合并单元 + if (cellRangeAddr.isInRange(curRowIndex - 1, curColIndex)) { + sheet.removeMergedRegion(i); + cellRangeAddr.setLastRow(curRowIndex); + sheet.addMergedRegion(cellRangeAddr); + isMerged = true; + } + } + // 若上一个单元格未被合并,则新增合并单元 + if (!isMerged) { + CellRangeAddress cellRangeAddress = new CellRangeAddress(curRowIndex - 1, curRowIndex, curColIndex, curColIndex); + sheet.addMergedRegion(cellRangeAddress); + } + } + } + + @Override + public void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Head head, Integer integer, Integer integer1, Boolean aBoolean) { + + } + + @Override + public void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell, Head head, Integer integer, Boolean aBoolean) { + + } +} + diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/performance/util/MultiColumnMergeStrategy.java b/pmapi/src/main/java/com/ningdatech/pmapi/performance/util/MultiColumnMergeStrategy.java new file mode 100644 index 0000000..154ee6c --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/performance/util/MultiColumnMergeStrategy.java @@ -0,0 +1,109 @@ +package com.ningdatech.pmapi.performance.util; + +import com.alibaba.excel.metadata.Head; +import com.alibaba.excel.write.merge.AbstractMergeStrategy; +import com.alibaba.fastjson.JSONObject; +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.CellType; +import org.apache.poi.ss.usermodel.Sheet; +import org.apache.poi.ss.util.CellRangeAddress; + +import java.util.ArrayList; +import java.util.List; + +/** + * 指定列单元格合并策略 + * + * @author CMM + * @since 2023/08/17 11:26 + */ + +public class MultiColumnMergeStrategy extends AbstractMergeStrategy { + + // 合并的列编号,从0开始,指定的index或自己按字段顺序数 + private Integer startCellIndex = 0; + private Integer endCellIndex = 0; + + // 数据集大小,用于区别结束行位置 + private Integer maxRow = 0; + + // 禁止无参声明 + private MultiColumnMergeStrategy() { + } + + /** + * 每行每列都会进入,循环注意条件限制 + */ + @Override + protected void merge(Sheet sheet, Cell cell, Head head, Integer relativeRowIndex) { + int currentCellIndex = cell.getColumnIndex(); + int currentRowIndex = cell.getRowIndex(); + + // 判断该列是否需要合并 + if (currentCellIndex < startCellIndex || currentCellIndex > endCellIndex) { + return; + } + + Object curData = cell.getCellType() == CellType.STRING ? cell.getStringCellValue() : cell.getNumericCellValue(); + String currentCellValue = curData.toString(); + + List rowList; + if (dataList.size() > currentRowIndex - 1) { + rowList = dataList.get(currentRowIndex - 1); + } else { + rowList = new ArrayList<>(); + dataList.add(rowList); + } + rowList.add(currentCellValue); + + // 结束的位置触发下最后一次没完成的合并 + if (relativeRowIndex == (maxRow - 1) && currentCellIndex == endCellIndex) { + System.out.println(JSONObject.toJSONString(dataList)); + List tempList = null; + Integer tempIndex = null; + for (int i = 0; i < dataList.size(); i++) { + if (tempList == null) { + tempList = dataList.get(i); + tempIndex = i; + continue; + } + List currList = dataList.get(i); + if (tempList.equals(currList)) { + if (i >= dataList.size() - 1) { + // 结束的位置触发下最后一次没完成的合并 + for (int j = 0; j < tempList.size(); j++) { + sheet.addMergedRegionUnsafe(new CellRangeAddress(tempIndex + 1, i + 1, startCellIndex + j, startCellIndex + j)); + } + } + continue; + } + + // 当前行数据和上一行数据不同且上面有多行相同数据时触发合并 + if (i - tempIndex > 1) { + for (int j = 0; j < tempList.size(); j++) { + sheet.addMergedRegionUnsafe(new CellRangeAddress(tempIndex + 1, i, startCellIndex + j, startCellIndex + j)); + } + } + + + tempIndex = i; + tempList = currList; + + + } + + } + } + + + public MultiColumnMergeStrategy(Integer maxRow, Integer startCellIndex, Integer endCellIndex) { + this.startCellIndex = startCellIndex; + this.endCellIndex = endCellIndex; + this.maxRow = maxRow; + } + + // 记录上一次合并的信息 + private final List> dataList = new ArrayList<>(); +} + +