Browse Source

项目库导出修改

tags/24080901
CMM 1 year ago
parent
commit
905827cc57
13 changed files with 443 additions and 193 deletions
  1. +5
    -0
      pmapi/pom.xml
  2. +1
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/common/constant/CommonConst.java
  3. +6
    -6
      pmapi/src/main/java/com/ningdatech/pmapi/projectlib/constant/ImportTemplateConstant.java
  4. +10
    -4
      pmapi/src/main/java/com/ningdatech/pmapi/projectlib/controller/AnnualPlanController.java
  5. +6
    -5
      pmapi/src/main/java/com/ningdatech/pmapi/projectlib/enumeration/ProjectLibFlagEnum.java
  6. +168
    -123
      pmapi/src/main/java/com/ningdatech/pmapi/projectlib/manage/AnnualPlanLibManage.java
  7. +66
    -52
      pmapi/src/main/java/com/ningdatech/pmapi/projectlib/model/dto/AnnualLibImportDTO.java
  8. +92
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/projectlib/model/entity/AnalysisEventMonitor.java
  9. +3
    -3
      pmapi/src/main/java/com/ningdatech/pmapi/projectlib/model/req/ProjectListReq.java
  10. +80
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/projectlib/utils/MergeUtil.java
  11. BIN
      pmapi/src/main/resources/template/丽水市2023年数字化项目年度计划编辑表.xls
  12. +6
    -0
      pom.xml
  13. BIN
      template/丽水市2023年数字化项目年度计划编辑表.xls

+ 5
- 0
pmapi/pom.xml View File

@@ -262,6 +262,11 @@
<groupId>com.itextpdf</groupId>
<artifactId>html2pdf</artifactId>
</dependency>
<!--导入导出-->
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-base</artifactId>
</dependency>


</dependencies>


+ 1
- 0
pmapi/src/main/java/com/ningdatech/pmapi/common/constant/CommonConst.java View File

@@ -45,6 +45,7 @@ public interface CommonConst {
String NEW_CONSTRUCTION = "新建";
String CONTINUED_CONSTRUCTION = "续建";
String MONTH = "月";
String ZHI = "至";





+ 6
- 6
pmapi/src/main/java/com/ningdatech/pmapi/projectlib/constant/ImportTemplateConstant.java View File

@@ -1,6 +1,6 @@
package com.ningdatech.pmapi.projectlib.constant;

import com.ningdatech.pmapi.projectlib.enumeration.ImportTemplateEnum;
import com.ningdatech.pmapi.projectlib.enumeration.ProjectLibFlagEnum;

import java.util.*;

@@ -15,16 +15,16 @@ import java.util.*;
*/
public class ImportTemplateConstant {

public static final List<String> ANNUAL_PLAN_COL_LIST = Arrays.asList("序号","项目id","项目名称","建设内容","建设依据","建设性质","建设起止年限(填写到月)", "总投资", "自有资金", "政府投资-本级财政","政府投资-上级补助资金","银行贷款","其他","一季度","二季度","三季度","四季度","建设单位","项目联系人","项目分管领导","备注");
public static final List<String> ANNUAL_PLAN_COL_LIST = Arrays.asList("序号","项目id","项目名称","建设内容","建设依据","建设性质","建设起止年限(填写到月)", "总投资", "自有资金","年度投资额","政府投资-本级财政","政府投资-上级补助资金","银行贷款","其他","一季度","二季度","三季度","四季度","建设单位","项目联系人","项目分管领导","备注");

private static final Map<ImportTemplateEnum, List<String>> IMPORT_TEMPLATE_MAP;
private static final Map<ProjectLibFlagEnum, List<String>> IMPORT_TEMPLATE_MAP;

static {
IMPORT_TEMPLATE_MAP = new HashMap<>(ImportTemplateEnum.values().length);
IMPORT_TEMPLATE_MAP.put(ImportTemplateEnum.ANNUAL_PLAN, ANNUAL_PLAN_COL_LIST);
IMPORT_TEMPLATE_MAP = new HashMap<>(ProjectLibFlagEnum.values().length);
IMPORT_TEMPLATE_MAP.put(ProjectLibFlagEnum.ANNUAL_PLAN, ANNUAL_PLAN_COL_LIST);
}

public static List<String> getTemplateTitle(ImportTemplateEnum template) {
public static List<String> getTemplateTitle(ProjectLibFlagEnum template) {
return IMPORT_TEMPLATE_MAP.getOrDefault(template, Collections.emptyList());
}



+ 10
- 4
pmapi/src/main/java/com/ningdatech/pmapi/projectlib/controller/AnnualPlanController.java View File

@@ -2,7 +2,7 @@ package com.ningdatech.pmapi.projectlib.controller;

import com.ningdatech.basic.model.PageVo;
import com.ningdatech.log.annotation.WebLog;
import com.ningdatech.pmapi.projectlib.enumeration.ImportTemplateEnum;
import com.ningdatech.pmapi.projectlib.enumeration.ProjectLibFlagEnum;
import com.ningdatech.pmapi.projectlib.manage.AnnualPlanLibManage;
import com.ningdatech.pmapi.projectlib.model.dto.ProjectDTO;
import com.ningdatech.pmapi.projectlib.model.req.ProjectApprovedReq;
@@ -65,8 +65,8 @@ public class AnnualPlanController {
@PostMapping("/importAnnualPlan")
@ApiOperation("导入年度计划")
@WebLog("导入年度计划")
public void importAnnualPlan(@RequestParam("template") ImportTemplateEnum template, MultipartFile file) {
annualPlanLibManage.importAnnualPlan(template,file);
public void importAnnualPlan(@RequestParam("importFlag") ProjectLibFlagEnum importFlag, MultipartFile file) {
annualPlanLibManage.importAnnualPlan(importFlag,file);
}

@PostMapping("/modify")
@@ -77,9 +77,15 @@ public class AnnualPlanController {
}

@PostMapping("/exportList")
@ApiOperation("项目库列表|编辑表】导出")
@ApiOperation("项目(增补)库列表导出")
public void exportList(@Valid @RequestBody ProjectListReq param, HttpServletResponse response) {
annualPlanLibManage.exportList(param, response);
}

@PostMapping("/exportModifyList")
@ApiOperation("项目(增补)库编辑表导出")
public void exportModifyList(@Valid @RequestBody ProjectListReq param, HttpServletResponse response) {
annualPlanLibManage.exportModifyList(param, response);
}

}

pmapi/src/main/java/com/ningdatech/pmapi/projectlib/enumeration/ImportTemplateEnum.java → pmapi/src/main/java/com/ningdatech/pmapi/projectlib/enumeration/ProjectLibFlagEnum.java View File

@@ -4,24 +4,25 @@ import lombok.Getter;

/**
* <p>
* 导入模版枚举
* 项目库标志枚举
* </p>
*
* @author WendyYang
* @since 2022-11-04
*/
@Getter
public enum ImportTemplateEnum {
public enum ProjectLibFlagEnum {

/**
* 通用导入模版枚举
* 项目库标志枚举
*/

ANNUAL_PLAN("年度计划(增补)库导入");
ANNUAL_PLAN("年度计划库"),
ANNUAL_PLAN_SUPPLEMENT("年度计划增补库");

private final String value;

ImportTemplateEnum(String value) {
ProjectLibFlagEnum(String value) {
this.value = value;
}


+ 168
- 123
pmapi/src/main/java/com/ningdatech/pmapi/projectlib/manage/AnnualPlanLibManage.java View File

@@ -1,12 +1,11 @@
package com.ningdatech.pmapi.projectlib.manage;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.afterturn.easypoi.excel.entity.TemplateExportParams;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
@@ -14,7 +13,6 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ningdatech.basic.exception.BizException;
import com.ningdatech.basic.model.PageVo;
import com.ningdatech.basic.util.CollUtils;
import com.ningdatech.basic.util.ValidUtil;
import com.ningdatech.pmapi.common.constant.CommonConst;
import com.ningdatech.pmapi.common.enumeration.CommonEnum;
import com.ningdatech.pmapi.common.helper.UserInfoHelper;
@@ -23,35 +21,42 @@ import com.ningdatech.pmapi.common.statemachine.util.StateMachineUtils;
import com.ningdatech.pmapi.common.util.ExcelDownUtil;
import com.ningdatech.pmapi.datascope.model.DataScopeDTO;
import com.ningdatech.pmapi.datascope.utils.DataScopeUtil;
import com.ningdatech.pmapi.projectlib.constant.ImportTemplateConstant;
import com.ningdatech.pmapi.projectlib.enumeration.ImportTemplateEnum;
import com.ningdatech.pmapi.expert.constant.ExpertUserInfoSensitiveFieldEnum;
import com.ningdatech.pmapi.projectlib.enumeration.ProjectLibFlagEnum;
import com.ningdatech.pmapi.projectlib.enumeration.ProjectRenewalApprovalStatusEnum;
import com.ningdatech.pmapi.projectlib.enumeration.ProjectStatusEnum;
import com.ningdatech.pmapi.projectlib.helper.ProjectHelper;
import com.ningdatech.pmapi.projectlib.model.dto.AnnualLibImportDTO;
import com.ningdatech.pmapi.projectlib.model.dto.ProjectDTO;
import com.ningdatech.pmapi.projectlib.model.entity.Project;
import com.ningdatech.pmapi.projectlib.model.entity.ProjectRenewalFundDeclaration;
import com.ningdatech.pmapi.projectlib.model.req.ProjectApprovedReq;
import com.ningdatech.pmapi.projectlib.model.req.ProjectIdReq;
import com.ningdatech.pmapi.projectlib.model.req.ProjectListReq;
import com.ningdatech.pmapi.projectlib.model.req.StartProjectDeclareReq;
import com.ningdatech.pmapi.projectlib.model.vo.AnnualPlanListItemVO;
import com.ningdatech.pmapi.projectlib.service.INdProjectStatusChangeService;
import com.ningdatech.pmapi.projectlib.service.IProjectRenewalFundDeclarationService;
import com.ningdatech.pmapi.projectlib.service.IProjectService;
import com.ningdatech.pmapi.user.security.auth.model.UserFullInfoDTO;
import com.ningdatech.pmapi.user.util.LoginUserUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.*;
import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

import static com.ningdatech.pmapi.expert.constant.ExpertUserInfoSensitiveFieldEnum.UnitType.list;
import static com.ningdatech.pmapi.projectlib.enumeration.ProjectStatusEnum.*;

/**
@@ -71,6 +76,7 @@ public class AnnualPlanLibManage {
private final StateMachineUtils stateMachine;
private final INdProjectStatusChangeService statusChangeService;
private final UserInfoHelper userInfoHelper;
private final IProjectRenewalFundDeclarationService projectRenewalFundDeclarationService;

/**
* 年度计划查询状态
@@ -169,112 +175,6 @@ public class AnnualPlanLibManage {
projectService.updateById(project);
}

@Transactional(rollbackFor = Exception.class)
public void importAnnualPlan(ImportTemplateEnum template, MultipartFile file) {
String contentType = file.getContentType();
if (!contentType.equals(ExcelUtil.XLS_CONTENT_TYPE) &&
!contentType.equals(ExcelUtil.XLSX_CONTENT_TYPE)
) {
throw BizException.wrap("导入失败,不支持的文件类型,请按照提供的模板导入文件!");
}
try (InputStream inputStream = file.getInputStream();
ExcelReader reader = ExcelUtil.getReader(inputStream)) {
Map<String, String> alias;
List<String> title = ImportTemplateConstant.getTemplateTitle(template);
switch (template) {
case ANNUAL_PLAN:
alias = new HashMap<>(title.size());
alias.put(title.get(0), "id");
alias.put(title.get(1), "projectId");
alias.put(title.get(2), "projectName");
alias.put(title.get(3), "projectIntroduction");
alias.put(title.get(4), "buildBasis");
alias.put(title.get(5), "isFirst");
alias.put(title.get(6), "buildCycle");
alias.put(title.get(7), "declaredAmount");
alias.put(title.get(8), "annualPlanAmount");
alias.put(title.get(9), "declareHaveAmount");
alias.put(title.get(10), "declareGovOwnFinanceAmount");
alias.put(title.get(11), "declareGovSuperiorFinanceAmount");
alias.put(title.get(12), "declareBankLendingAmount");
alias.put(title.get(13), "declareOtherAmount");
alias.put(title.get(14), "firstQuarter");
alias.put(title.get(15), "secondQuarter");
alias.put(title.get(16), "thirdQuarter");
alias.put(title.get(17), "fourthQuarter");
alias.put(title.get(18), "buildUnitName");
alias.put(title.get(19), "contactName");
alias.put(title.get(20), "responsibleMan");
alias.put(title.get(21), "projectRemarks");
reader.setHeaderAlias(alias);
importAnnualPlanData(reader.readAll(AnnualLibImportDTO.class));
break;
default:
throw new BizException("不支持的数据导入类型");
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}

private void importAnnualPlanData(List<AnnualLibImportDTO> importDataList) {
if (CollectionUtils.isEmpty(importDataList)) {
return;
}
List<Project> projectList = new ArrayList<>();
List<Long> projectIds = CollUtils.fieldList(importDataList, AnnualLibImportDTO::getProjectId);
Assert.isTrue(projectIds.size() == importDataList.size(), "项目ID不可重复");
Long userId = LoginUserUtil.getUserId();
LocalDateTime now = LocalDateTime.now();
importDataList.forEach(w -> {
Project project = new Project();
project.setCreateBy(userId);
project.setCreateOn(now);
project.setUpdateBy(userId);
project.setUpdateOn(now);

project.setId(w.getProjectId());
project.setProjectName(w.getProjectName());
project.setProjectIntroduction(w.getProjectIntroduction());
// 建设依据(立项依据忽略)
if (CommonConst.NEW_CONSTRUCTION.equals(w.getIsFirst())){
project.setIsFirst(CommonEnum.YES.getCode());
}else if (CommonConst.CONTINUED_CONSTRUCTION.equals(w.getIsFirst())){
project.setIsFirst(CommonEnum.NO.getCode());
}
String buildCycle = w.getBuildCycle();
int index = buildCycle.indexOf(CommonConst.MONTH);
if (-1 == index){
throw new BizException("项目ID为:" + w.getProjectId() + "的建设起止年限格式不正确,请按照xx年xx月至xx年xx月的格式输入!");
}
String beginTime = buildCycle.substring(0, index + 1);
project.setBeginTime(beginTime);
String endTime = buildCycle.substring(index + 2);
project.setEndTime(endTime);
project.setDeclareAmount(w.getDeclaredAmount());
project.setAnnualPlanAmount(w.getAnnualPlanAmount());
project.setDeclareHaveAmount(w.getDeclareHaveAmount());
project.setDeclareGovOwnFinanceAmount(w.getDeclareGovOwnFinanceAmount());
project.setDeclareGovSuperiorFinanceAmount(w.getDeclareGovSuperiorFinanceAmount());
project.setDeclareBankLendingAmount(w.getDeclareBankLendingAmount());
project.setDeclareOtherAmount(w.getDeclareOtherAmount());
project.setEngineeringSpeedOne(w.getFirstQuarter());
project.setEngineeringSpeedTwo(w.getSecondQuarter());
project.setEngineeringSpeedThree(w.getThirdQuarter());
project.setEngineeringSpeedFour(w.getFourthQuarter());

project.setBuildOrgName(w.getBuildUnitName());
project.setContactName(w.getContactName());
project.setResponsibleMan(w.getResponsibleMan());
project.setProjectRemarks(w.getProjectRemarks());
projectList.add(project);
});
LambdaQueryWrapper<Project> delQuery = Wrappers.lambdaQuery(Project.class)
.in(Project::getId, projectIds);
projectService.remove(delQuery);
projectService.saveBatch(projectList);
}

public void updateAnnualPlan(ProjectDTO req) {
Project project = BeanUtil.copyProperties(req, Project.class);
projectService.updateById(project);
@@ -295,15 +195,12 @@ public class AnnualPlanLibManage {

ExcelExportWriter excelExportWriter = new ExcelExportWriter();

Integer tableFlag = param.getTableFlag();
if (Objects.isNull(tableFlag)) {
throw new BizException("请传入要导出的表格类型!");
}
ProjectLibFlagEnum projectLibFlag = param.getProjectLibFlag();
String fileName = null;
if (tableFlag == 0) {
fileName = "年度计划库编辑表";
} else if (tableFlag == 1) {
if (ProjectLibFlagEnum.ANNUAL_PLAN.equals(projectLibFlag)){
fileName = "年度计划库列表";
}else if (ProjectLibFlagEnum.ANNUAL_PLAN_SUPPLEMENT.equals(projectLibFlag)){
fileName = "年度计划增补库列表";
}
excelExportWriter.setFileName(fileName);
List<String> sheetsNames = new ArrayList<>();
@@ -356,4 +253,152 @@ public class AnnualPlanLibManage {
}
return user;
}

@Transactional(rollbackFor = Exception.class)
public void importAnnualPlan(ProjectLibFlagEnum importFlag, MultipartFile file) {
Long userId = LoginUserUtil.getUserId();
ImportParams params = new ImportParams();
// 标题行数
params.setTitleRows(2);
// 从第几行开始,因为第一、二个大标题被上面的参数给占了,所以不是5
params.setHeadRows(3);
// 表格数量
params.setSheetNum(2);
List<AnnualLibImportDTO> list = null;
try {
list = ExcelImportUtil.importExcel(file.getInputStream(), AnnualLibImportDTO.class, params);
} catch (Exception e) {
throw new BizException(e.getMessage());
}
// 筛选出导入的新建项目
List<AnnualLibImportDTO> newList = list.stream()
.filter(d -> CommonConst.NEW_CONSTRUCTION.equals(d.getIsFirst()))
.collect(Collectors.toList());
List<Project> projectList = newList.stream().map(n -> {
Project project = new Project();
assemblyProjectInfo(n, project);
// 根据传入标志判断是否临时增补
if (ProjectLibFlagEnum.ANNUAL_PLAN.equals(importFlag)){
project.setIsTemporaryAugment(CommonEnum.NO.getCode());
}else if (ProjectLibFlagEnum.ANNUAL_PLAN_SUPPLEMENT.equals(importFlag)){
project.setIsTemporaryAugment(CommonEnum.YES.getCode());
}
project.setCreateBy(userId);
project.setUpdateBy(userId);
project.setCreateOn(LocalDateTime.now());
project.setUpdateOn(LocalDateTime.now());
return project;
}).collect(Collectors.toList());
// 保存到项目库中
projectService.saveBatch(projectList);

// 筛选出导入的续建项目
List<AnnualLibImportDTO> continuedList = list.stream()
.filter(d -> CommonConst.CONTINUED_CONSTRUCTION.equals(d.getIsFirst()))
.collect(Collectors.toList());
List<ProjectRenewalFundDeclaration> renewalFundDeclarationList = continuedList.stream().map(c -> {
ProjectRenewalFundDeclaration renewalFundDeclaration = new ProjectRenewalFundDeclaration();
BeanUtils.copyProperties(c, renewalFundDeclaration);
renewalFundDeclaration.setAnnualPaymentAmount(c.getAnnualPlanAmount());
renewalFundDeclaration.setOtherAmount(c.getDeclareOtherAmount());
renewalFundDeclaration.setApprovalStatus(ProjectRenewalApprovalStatusEnum.PENDING.name());
renewalFundDeclaration.setCreateOn(LocalDateTime.now());
renewalFundDeclaration.setUpdateOn(LocalDateTime.now());
return renewalFundDeclaration;
}).collect(Collectors.toList());
// 保存到续建项目资金库中
projectRenewalFundDeclarationService.saveBatch(renewalFundDeclarationList);
}

private void assemblyProjectInfo(AnnualLibImportDTO data, Project project) {
project.setId(data.getProjectId());
project.setProjectName(data.getProjectName());
project.setProjectIntroduction(data.getProjectIntroduction());
// 建设依据忽略
project.setIsFirst(CommonConst.NEW_CONSTRUCTION.equals(data.getIsFirst()) ? 1 : 0);
String[] dataArr = data.getBuildCycle().split(CommonConst.ZHI);
if (CollectionUtils.isEmpty(Arrays.asList(dataArr))){
throw new BizException("项目ID为:" + data.getProjectId() + "的建设起止年限格式不正确,请按照xx年xx月至xx年xx月的格式输入!");
}
project.setBeginTime(dataArr[0].trim());
project.setEndTime(dataArr[1].trim());
project.setDeclareAmount(data.getDeclaredAmount());
project.setAnnualPlanAmount(data.getAnnualPlanAmount());
project.setDeclareHaveAmount(data.getDeclareHaveAmount());
project.setDeclareGovOwnFinanceAmount(data.getDeclareGovOwnFinanceAmount());
project.setDeclareGovSuperiorFinanceAmount(data.getDeclareGovSuperiorFinanceAmount());
project.setDeclareBankLendingAmount(data.getDeclareBankLendingAmount());
project.setDeclareOtherAmount(data.getDeclareOtherAmount());
project.setEngineeringSpeedOne(data.getFirstQuarter());
project.setEngineeringSpeedTwo(data.getSecondQuarter());
project.setEngineeringSpeedThree(data.getThirdQuarter());
project.setEngineeringSpeedFour(data.getFourthQuarter());
project.setBuildOrgName(data.getBuildUnitName());
project.setContactName(data.getContactName());
project.setResponsibleMan(data.getResponsibleMan());
project.setProjectRemarks(data.getProjectRemarks());
}

public void exportModifyList(ProjectListReq param, HttpServletResponse response) {
ProjectLibFlagEnum projectLibFlag = param.getProjectLibFlag();
int year = LocalDateTime.now().getYear();
Integer isTemporaryAugment = null;
String fileName = null;
// 设置excel的文件名称和是否增补
if (ProjectLibFlagEnum.ANNUAL_PLAN.equals(projectLibFlag)){
isTemporaryAugment = 0;
fileName = "丽水市" + year + "年数字化项目年度计划库编辑表";
}else if (ProjectLibFlagEnum.ANNUAL_PLAN_SUPPLEMENT.equals(projectLibFlag)){
isTemporaryAugment = 1;
fileName = "丽水市" + year + "年数字化项目年度计划增补库编辑表";
}
param.setIsTemporaryAugment(isTemporaryAugment);
param.setStatusList(CollUtils.fieldList(ANNUAL_PLAN_LIST_STATUS, ProjectStatusEnum::getCode));
LambdaQueryWrapper<Project> query = ProjectHelper.projectQuery(param);
query.orderByDesc(Project::getAnnualPlanAddTime);
List<Project> projects = projectService.list(query);
List<AnnualLibImportDTO> list = projects.stream().map(p -> {
AnnualLibImportDTO dto = new AnnualLibImportDTO();
BeanUtils.copyProperties(p, dto);
dto.setFirstQuarter(p.getEngineeringSpeedOne());
dto.setSecondQuarter(p.getEngineeringSpeedTwo());
dto.setThirdQuarter(p.getEngineeringSpeedThree());
dto.setFourthQuarter(p.getEngineeringSpeedFour());
return dto;
}).collect(Collectors.toList());

// 获取本地目录的年度计划编辑表Excel模板
File directory = new File("");
String templateName = "丽水市" + year + "年数字化项目年度计划编辑表";
String templatePath = directory.getAbsolutePath() + File.separator + "template" + File.separator + templateName + ".xls";
TemplateExportParams temp = new TemplateExportParams(templatePath);
HashMap<String, Object> map = new HashMap<>();
map.put("mapList", list);
Workbook workbook = ExcelExportUtil.exportExcel(temp, map);
if (workbook == null) {
throw new BizException("读取模板失败!");
}
// 重置响应对象
response.reset();
try {
response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + URLEncoder.encode(Objects.requireNonNull(fileName),"UTF-8") + ".xls");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
response.setContentType(ExcelUtil.XLS_CONTENT_TYPE);
response.setHeader("Pragma", "no-cache");
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", 0);
// 写出数据输出流到页面
try {
OutputStream output = response.getOutputStream();
BufferedOutputStream bufferedOutPut = new BufferedOutputStream(output);
workbook.write(bufferedOutPut);
bufferedOutPut.flush();
bufferedOutPut.close();
output.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

+ 66
- 52
pmapi/src/main/java/com/ningdatech/pmapi/projectlib/model/dto/AnnualLibImportDTO.java View File

@@ -1,5 +1,6 @@
package com.ningdatech.pmapi.projectlib.model.dto;

import cn.afterturn.easypoi.excel.annotation.Excel;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;

@@ -18,91 +19,104 @@ import java.math.BigDecimal;
@Data
public class AnnualLibImportDTO {

@ExcelProperty("序号")
@NotNull(message = "序号不能为空")
private Integer serialNumber;

@ExcelProperty("项目id")
@NotNull(message = "项目ID不能为空")
private Long projectId;

@ExcelProperty("项目名称")
@NotBlank(message = "项目名称不能为空")
private String projectName;

@NotBlank(message = "建设内容不能为空")
@ExcelProperty("建设内容")
private String projectIntroduction;

@NotBlank(message = "建设依据不能为空")
@ExcelProperty("建设依据")
private String buildBasis;

@ExcelProperty("建设性质")
@NotBlank(message = "建设性质不能为空")
private String isFirst;

@ExcelProperty("建设起止年限")
@NotBlank(message = "建设起止年限不能为空")
private String buildCycle;

@NotBlank(message = "总投资不能为空")
@ExcelProperty("总投资")
private BigDecimal declaredAmount;
@Excel(name = "项目进展",groupName = "到2022年底完成情况")
@NotNull(message = "项目进展不能为空")
private String projectProgress;
@Excel(name = "累计投资")
@NotNull(message = "累计投资不能为空")
private BigDecimal cumulativeInvest;

@NotNull(message = "年度投资额不能为空")
@ExcelProperty("年度投资额")
@Excel(name = "年度投资额",groupName = "2023年计划")
private BigDecimal annualPlanAmount;

@ExcelProperty("自有资金")
@NotNull(message = "自由资金不能为空")
@Excel(name = "自有资金",groupName = "资金来源")
private BigDecimal declareHaveAmount;

@ExcelProperty("政府投资-本级财政")
@Excel(name = "政府投资-本级财政资金")
@NotNull(message = "政府投资-本级财政不能为空")
private BigDecimal declareGovOwnFinanceAmount;

@ExcelProperty("政府投资-上级补助资金")
@Excel(name = "政府投资-上级补助资金")
@NotNull(message = "政府投资-上级补助资金不能为空")
private BigDecimal declareGovSuperiorFinanceAmount;

@ExcelProperty("银行贷款")
@Excel(name = "银行贷款")
@NotNull(message = "银行贷款不能为空")
private BigDecimal declareBankLendingAmount;

@ExcelProperty("其他")
@Excel(name = "国家、省补助",groupName = "资金来源")
@NotNull(message = "国家、省补助不能为空")
private BigDecimal govSuperiorFinanceAmount;
@Excel(name = "地方财政统筹")
@NotNull(message = "地方财政统筹不能为空")
private BigDecimal govOwnFinanceAmount;
@Excel(name = "建设单位自筹")
@NotNull(message = "建设单位自筹不能为空")
private BigDecimal haveAmount;
@Excel(name = "其他")
@NotNull(message = "其他不能为空")
private BigDecimal declareOtherAmount;

@ExcelProperty("一季度")
@Excel(name = "一季度",groupName = "进度和支付计划")
@NotBlank(message = "一季度不能为空")
private String firstQuarter;

@ExcelProperty("二季度")
@Excel(name = "二季度")
@NotBlank(message = "二季度不能为空")
private String secondQuarter;

@ExcelProperty("三季度")
@Excel(name = "三季度")
@NotBlank(message = "三季度不能为空")
private String thirdQuarter;

@ExcelProperty("四季度")
@Excel(name = "四季度")
@NotBlank(message = "四季度不能为空")
private String fourthQuarter;

@ExcelProperty("建设单位")
@NotNull(message = "序号不能为空")
@Excel(name = "序号")
private Integer serialNumber;

@Excel(name = "项目id")
@NotNull(message = "项目ID不能为空")
private Long projectId;

@Excel(name = "项目名称")
@NotBlank(message = "项目名称不能为空")
private String projectName;

@NotBlank(message = "建设内容不能为空")
@Excel(name = "建设内容")
private String projectIntroduction;

@NotBlank(message = "建设依据不能为空")
@Excel(name = "建设依据")
private String buildBasis;

@Excel(name = "建设性质")
@NotBlank(message = "建设性质不能为空")
private String isFirst;

@Excel(name = "建设周期")
@NotBlank(message = "建设周期不能为空")
private String constructionCycle;

@Excel(name = "建设起止年限(填写到月)")
@NotBlank(message = "建设起止年限不能为空")
private String buildCycle;

@NotBlank(message = "总投资不能为空")
@Excel(name = "总投资")
private BigDecimal declaredAmount;

@Excel(name = "建设单位")
@NotBlank(message = "建设单位不能为空")
private String buildUnitName;

@ExcelProperty("项目联系人")
@Excel(name = "项目联系人")
@NotBlank(message = "项目联系人不能为空")
private String contactName;

@ExcelProperty("项目分管领导")
@Excel(name = "项目分管领导")
@NotBlank(message = "项目分管领导不能为空")
private String responsibleMan;

@ExcelProperty("备注")
@Excel(name = "备注")
private String projectRemarks;

}

+ 92
- 0
pmapi/src/main/java/com/ningdatech/pmapi/projectlib/model/entity/AnalysisEventMonitor.java View File

@@ -0,0 +1,92 @@
package com.ningdatech.pmapi.projectlib.model.entity;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ningdatech.basic.exception.BizException;
import com.ningdatech.basic.util.CollUtils;
import com.ningdatech.pmapi.common.constant.CommonConst;
import com.ningdatech.pmapi.projectlib.service.IProjectService;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.RequiredArgsConstructor;

import java.util.*;

/**
* @author CMM
* @since 2023/04/17 18:26
*/
@Data
public class AnalysisEventMonitor extends AnalysisEventListener<Map<Integer, String>> {

private final List<Project> records = new ArrayList<>();

/**
* 存储Key
*/
Map<Integer, String> key = new HashMap<>();
/**
* keyList
*/
List<String> keyList = new ArrayList<>();

@Override
public void onException(Exception exception, AnalysisContext context) throws Exception {
super.onException(exception, context);
throw BizException.wrap("导入年度计划解析失败");
}

@Override
public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
Set<Integer> integerSet = headMap.keySet();
for (Integer integer : integerSet) {
keyList.add(headMap.get(integer));
}
key.putAll(headMap);
}

@Override
public void invoke(Map<Integer, String> integerStringMap, AnalysisContext context) {
//Project project = new Project();
//project.setId(data.getProjectId());
//project.setProjectName(data.getProjectName());
//project.setProjectIntroduction(data.getProjectIntroduction());
//// 建设依据忽略
//project.setIsFirst(CommonConst.NEW_CONSTRUCTION.equals(data.getIsFirst()) ? 1 : 0);
//String[] dataArr = data.getBuildCycle().split(CommonConst.ZHI);
//project.setBeginTime(dataArr[0].trim());
//project.setEndTime(dataArr[1].trim());
//project.setDeclareAmount(data.getDeclaredAmount());
//project.setAnnualPlanAmount(data.getAnnualPlanAmount());
//project.setDeclareHaveAmount(data.getDeclareHaveAmount());
//project.setDeclareGovOwnFinanceAmount(data.getDeclareGovOwnFinanceAmount());
//project.setDeclareGovSuperiorFinanceAmount(data.getDeclareGovSuperiorFinanceAmount());
//project.setDeclareBankLendingAmount(data.getDeclareBankLendingAmount());
//project.setDeclareOtherAmount(data.getDeclareOtherAmount());
//project.setEngineeringSpeedOne(data.getFirstQuarter());
//project.setEngineeringSpeedTwo(data.getSecondQuarter());
//project.setEngineeringSpeedThree(data.getThirdQuarter());
//project.setEngineeringSpeedFour(data.getFourthQuarter());
//project.setBuildOrgName(data.getBuildUnitName());
//project.setContactName(data.getContactName());
//project.setResponsibleMan(data.getResponsibleMan());
//project.setProjectRemarks(data.getProjectRemarks());
//records.add(project);
}

@Override
public void doAfterAllAnalysed(AnalysisContext context) {
//if (records.isEmpty()) {
// throw BizException.wrap("导入年度计划为空");
//}
//List<Long> projectIds = CollUtils.fieldList(records, Project::getId);
//long count = projectService.count(Wrappers.lambdaQuery(Project.class)
// .in(Project::getId, projectIds));
//if (count != records.size()) {
// throw BizException.wrap("请确保所有项目都存在");
//}
//projectService.updateBatchById(records);
}
}

+ 3
- 3
pmapi/src/main/java/com/ningdatech/pmapi/projectlib/model/req/ProjectListReq.java View File

@@ -2,12 +2,12 @@ package com.ningdatech.pmapi.projectlib.model.req;

import com.ningdatech.basic.model.PagePo;
import com.ningdatech.pmapi.common.enumeration.ExportOptionEnum;
import com.ningdatech.pmapi.projectlib.enumeration.ProjectLibFlagEnum;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.*;
import org.springframework.format.annotation.DateTimeFormat;

import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
@@ -92,6 +92,6 @@ public class ProjectListReq extends PagePo {
@ApiModelProperty("导出选项")
private List<ExportOptionEnum> exportOptionList;

@ApiModelProperty(value = "表格类型",allowableValues = "0,1")
private Integer tableFlag;
@ApiModelProperty(value = "项目库标志枚举")
private ProjectLibFlagEnum projectLibFlag;
}

+ 80
- 0
pmapi/src/main/java/com/ningdatech/pmapi/projectlib/utils/MergeUtil.java View File

@@ -0,0 +1,80 @@
package com.ningdatech.pmapi.projectlib.utils;

import java.util.List;
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 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 lombok.Data;

/**
* @description: 多表头excel导出合并单元格策略
* @author:YJ
**/
@Data
public class MergeUtil implements CellWriteHandler {
private int[] mergeColumnIndex;
private int mergeRowIndex;

public MergeUtil() {
}

public MergeUtil(int mergeRowIndex, int[] mergeColumnIndex) {
this.mergeRowIndex = mergeRowIndex;
this.mergeColumnIndex = mergeColumnIndex;
}


@Override
public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, List<WriteCellData<?>> list, Cell cell, Head head, Integer integer, Boolean aBoolean) {
// 当前行
int curRowIndex = cell.getRowIndex();
// 当前列
int curColIndex = cell.getColumnIndex();

if (curRowIndex > mergeRowIndex) {
for (int i = 0; i < mergeColumnIndex.length; i++) {
if (curColIndex == mergeColumnIndex[i]) {
mergeWithPrevRow(writeSheetHolder, cell, curRowIndex, curColIndex);
break;
}
}
}
}


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<CellRangeAddress> mergedRegions = sheet.getMergedRegions();
boolean isMerged = false;
for (int i = 0; i < mergedRegions.size() && !isMerged; i++) {
CellRangeAddress cellRangeAddr = mergedRegions.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);
}
}
}
}


BIN
pmapi/src/main/resources/template/丽水市2023年数字化项目年度计划编辑表.xls View File


+ 6
- 0
pom.xml View File

@@ -175,6 +175,12 @@
<artifactId>html2pdf</artifactId>
<version>2.0.2</version>
</dependency>
<!--导入导出-->
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-base</artifactId>
<version>4.2.0</version>
</dependency>

</dependencies>
</dependencyManagement>


BIN
template/丽水市2023年数字化项目年度计划编辑表.xls View File


Loading…
Cancel
Save