Commit 02dc099b53ea7ceaef1654c51516007d07b90372

Authored by 房远帅
1 parent 552e43ae

资金协调手续:资金协调手续打印

... ... @@ -178,6 +178,12 @@ public class GetFundCoordinationBo extends BaseBo<FundCoordination> {
178 178 private String status;
179 179
180 180 /**
  181 + * 办事处名称
  182 + */
  183 + @ApiModelProperty("办事处名称")
  184 + private String deptName;
  185 +
  186 + /**
181 187 * 订货单位主键集合
182 188 */
183 189 @ApiModelProperty("订货单位主键集合")
... ...
... ... @@ -28,6 +28,7 @@ import com.lframework.xingyun.sc.bo.ledger.fund.GetFundCoordinationBo;
28 28 import com.lframework.xingyun.sc.bo.ledger.fund.QueryFundCoordinationBo;
29 29 import com.lframework.xingyun.sc.bo.order.GetPurchaseOrderInfoBo;
30 30 import com.lframework.xingyun.sc.entity.*;
  31 +import com.lframework.xingyun.sc.handlers.TransactorHandler;
31 32 import com.lframework.xingyun.sc.service.customer.CustomerCreditService;
32 33 import com.lframework.xingyun.sc.service.ledger.*;
33 34 import com.lframework.xingyun.sc.service.order.PurchaseOrderInfoService;
... ... @@ -108,6 +109,8 @@ public class FundCoordinationController extends DefaultBaseController {
108 109 private CustomerShortService customerShortService;
109 110 @Resource
110 111 private CustomerCreditService customerCreditService;
  112 + @Resource
  113 + private TransactorHandler transactorHandler;
111 114
112 115 /**
113 116 * 查询列表
... ... @@ -504,7 +507,49 @@ public class FundCoordinationController extends DefaultBaseController {
504 507 List<PendingDeliveryOrder> pendingDeliveryOrderList = pendingDeliveryOrderService.query(vo2);
505 508 if (CollectionUtils.isNotEmpty(pendingDeliveryOrderList)) {
506 509 data.setPendingDeliveryOrderList(pendingDeliveryOrderList);
  510 + BigDecimal totalPendingQuantity = pendingDeliveryOrderList.stream()
  511 + .map(order -> {
  512 + String totalStr = Objects.toString(order.getTotalQuantity(), "").trim();
  513 + String dispatchedStr = Objects.toString(order.getDispatchedQuantity(), "").trim();
  514 +
  515 + // 空字符串视为 "0"
  516 + if (totalStr.isEmpty()) totalStr = "0";
  517 + if (dispatchedStr.isEmpty()) dispatchedStr = "0";
  518 +
  519 + try {
  520 + BigDecimal total = new BigDecimal(totalStr);
  521 + BigDecimal dispatched = new BigDecimal(dispatchedStr);
  522 + return total.subtract(dispatched); // 待发 = 总 - 已发
  523 + } catch (NumberFormatException e) {
  524 + // 非法数据按 0 处理(可选:记录日志)
  525 + return BigDecimal.ZERO;
  526 + }
  527 + })
  528 + .reduce(BigDecimal.ZERO, BigDecimal::add);
  529 + String resultStr = totalPendingQuantity.stripTrailingZeros().toPlainString();
  530 + data.setPendingDeliveryOrderQuantity(resultStr);
507 531 }
  532 + //办事处
  533 + String deptCode = transactorHandler.returnDeptCode(fundCoordination.getApplicant());
  534 + String deptName = "";
  535 + if ("BF".equals(deptCode)) {
  536 + deptName = "北方";
  537 + } else if ("CZ".equals(deptCode)) {
  538 + deptName = "常州";
  539 + } else if ("DG".equals(deptCode)) {
  540 + deptName = "东莞";
  541 + } else if ("FS".equals(deptCode)) {
  542 + deptName = "佛山";
  543 + } else if ("NB".equals(deptCode)) {
  544 + deptName = "宁波";
  545 + } else if ("SZ".equals(deptCode)) {
  546 + deptName = "苏州";
  547 + } else if ("WZ".equals(deptCode)) {
  548 + deptName = "温州";
  549 + } else if ("ZT".equals(deptCode)) {
  550 + deptName = "紫铜";
  551 + }
  552 + data.setDeptName(deptName);
508 553 // 获取当前人员的待办任务数据
509 554 List<FlowTaskDto> flowTaskList = flowTaskWrapperMapper.queryTodoList(new QueryTodoTaskListVo(), SecurityUtil.getCurrentUser().getId());
510 555 if (CollectionUtils.isNotEmpty(flowTaskList)) {
... ... @@ -513,4 +558,520 @@ public class FundCoordinationController extends DefaultBaseController {
513 558 }
514 559 return data;
515 560 }
  561 +
  562 + @ApiOperation("资金协调手续打印")
  563 + @GetMapping("/printFundCoordination")
  564 + public void printFundCoordination(@NotBlank(message = "id不能为空") String id, HttpServletResponse response) throws IOException {
  565 + FundCoordination fundCoordination = fundCoordinationService.findById(id);
  566 +
  567 + GetFundCoordinationBo data = packFundCoordinationData(fundCoordination);
  568 +
  569 + // 设置响应头
  570 + setupResponse(response, fundCoordination.getCustomerShortName() + "-资金协调手续打印.xlsx");
  571 +
  572 + try {
  573 + // 加载模板文件
  574 + ClassPathResource templateResource = new ClassPathResource("templates/fundCoordinationTemplate.xlsx");
  575 + try (InputStream inputStream = templateResource.getStream();
  576 + Workbook workbook = new XSSFWorkbook(inputStream)) {
  577 + try {
  578 + Sheet sheet = workbook.getSheetAt(0);
  579 + processOrderingUnits(workbook,sheet, data.getFundOrderingUnitList());
  580 +
  581 + DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
  582 +
  583 + //审核人员
  584 + List<String> userIds = new ArrayList<>();
  585 + userIds.add(data.getOfficeClerk());
  586 + userIds.add(data.getOfficeSupervisor());
  587 + userIds.add(data.getMarketingDeputyDirector());
  588 + userIds.add(data.getFundManagementOperationDepartment());
  589 + userIds.add(data.getOperationsDepartmentSupervisor());
  590 + userIds.add(data.getMarketingDepartmentManager());
  591 + userIds.add(data.getFinanceDepartment());
  592 + userIds.add(data.getMarketingCenterSupervisor());
  593 + userIds.add(data.getGeneralManager());
  594 + Map<String, String> map = new HashMap<>();
  595 + if (CollectionUtils.isNotEmpty(userIds)) {
  596 + List<SysUser> list = sysUserService.listByUserId(userIds);
  597 + if (CollectionUtils.isNotEmpty(list)) {
  598 + map = list.stream().collect(Collectors.toMap(SysUser::getId, SysUser::getName));
  599 + }
  600 + }
  601 +
  602 + Map<String, Object> dataMap = new HashMap<>();
  603 + dataMap.put("deptName", data.getDeptName() == null ? "" : data.getDeptName());
  604 + dataMap.put("applicantName", data.getApplicantName() == null ? "" : data.getApplicantName());
  605 + dataMap.put("deptAndRole", data.getDeptAndRole() == null ? "" : data.getDeptAndRole());
  606 + dataMap.put("applicationDate", data.getApplicationDate() == null ? "" : data.getApplicationDate().format(dateFormatter));
  607 + dataMap.put("orderingUnitName", data.getOrderingUnitName() == null ? "" : data.getOrderingUnitName());
  608 + dataMap.put("customerShortName", data.getCustomerShortName() == null ? "" : data.getCustomerShortName());
  609 + dataMap.put("customerType", data.getCustomerType() == null ? "" : data.getCustomerType());
  610 + dataMap.put("unlimitedGuaranteeLetter", data.getUnlimitedGuaranteeLetter() == null ? "" : data.getUnlimitedGuaranteeLetter());
  611 + dataMap.put("settlementPeriod", data.getSettlementPeriod() == null ? "" : data.getSettlementPeriod());
  612 + dataMap.put("creditLimit", data.getCreditLimit() == null ? "" : data.getCreditLimit());
  613 + dataMap.put("orderDate", data.getOrderDate() == null ? "" : data.getOrderDate().format(dateFormatter));
  614 + dataMap.put("orderQuantity", data.getOrderQuantity() == null ? "" : data.getOrderQuantity().stripTrailingZeros().toPlainString());
  615 + dataMap.put("pendingDeliveryOrderQuantity", data.getPendingDeliveryOrderQuantity() == null ? "" : data.getPendingDeliveryOrderQuantity());
  616 + dataMap.put("requestedShipmentQuantity", data.getRequestedShipmentQuantity() == null ? "" : data.getRequestedShipmentQuantity());
  617 + dataMap.put("totalAccountsReceivable", data.getTotalAccountsReceivable() == null ? "" : data.getTotalAccountsReceivable());
  618 + dataMap.put("overdueReceivables", data.getOverdueReceivables() == null ? "" : data.getOverdueReceivables());
  619 + dataMap.put("agreedInternalReceivables", data.getAgreedInternalReceivables() == null ? "" : data.getAgreedInternalReceivables());
  620 + dataMap.put("requirementSpecification", data.getRequirementSpecification() == null ? "" : data.getRequirementSpecification());
  621 + dataMap.put("officeClerkName", data.getOfficeClerk() == null ? "" : map.get(data.getOfficeClerk()));
  622 + dataMap.put("officeClerkOpinion", data.getOfficeClerkOpinion() == null ? "" : data.getOfficeClerkOpinion());
  623 + dataMap.put("officeSupervisorName", data.getOfficeSupervisor() == null ? "" : map.get(data.getOfficeSupervisor()));
  624 + dataMap.put("officeSupervisorOpinion", data.getOfficeSupervisorOpinion() == null ? "" : data.getOfficeSupervisorOpinion());
  625 + dataMap.put("marketingDeputyDirectorName", data.getMarketingDeputyDirector() == null ? "" : map.get(data.getMarketingDeputyDirector()));
  626 + dataMap.put("marketingDeputyDirectorOpinion", data.getMarketingDeputyDirectorOpinion() == null ? "" : data.getMarketingDeputyDirectorOpinion());
  627 + dataMap.put("fundManagementOperationDepartmentName", data.getFundManagementOperationDepartment() == null ? "" : map.get(data.getFundManagementOperationDepartment()));
  628 + dataMap.put("fundManagementOperationDepartmentOpinion", data.getFundManagementOperationDepartmentOpinion() == null ? "" : data.getFundManagementOperationDepartmentOpinion());
  629 + dataMap.put("operationsDepartmentSupervisorName", data.getOperationsDepartmentSupervisor() == null ? "" : map.get(data.getOperationsDepartmentSupervisor()));
  630 + dataMap.put("operationsDepartmentSupervisorOpinion", data.getOperationsDepartmentSupervisorOpinion() == null ? "" : data.getOperationsDepartmentSupervisorOpinion());
  631 + dataMap.put("marketingDepartmentManagerName", data.getMarketingDepartmentManager() == null ? "" : map.get(data.getMarketingDepartmentManager()));
  632 + dataMap.put("marketingDepartmentManagerOpinion", data.getMarketingDepartmentManagerOpinion() == null ? "" : data.getMarketingDepartmentManagerOpinion());
  633 + dataMap.put("financeDepartmentName", data.getFinanceDepartment() == null ? "" : map.get(data.getFinanceDepartment()));
  634 + dataMap.put("financeDepartmentOpinion", data.getFinanceDepartmentOpinion() == null ? "" : data.getFinanceDepartmentOpinion());
  635 + dataMap.put("marketingCenterSupervisorName", data.getMarketingCenterSupervisor() == null ? "" : map.get(data.getMarketingCenterSupervisor()));
  636 + dataMap.put("marketingCenterSupervisorOpinion", data.getMarketingCenterSupervisorOpinion() == null ? "" : data.getMarketingCenterSupervisorOpinion());
  637 + dataMap.put("generalManagerName", data.getGeneralManager() == null ? "" : map.get(data.getGeneralManager()));
  638 + dataMap.put("generalManagerOpinion", data.getGeneralManagerOpinion() == null ? "" : data.getGeneralManagerOpinion());
  639 +
  640 + processTemplate(workbook, dataMap);
  641 +
  642 + // 写入响应流
  643 + workbook.write(response.getOutputStream());
  644 + response.getOutputStream().flush();
  645 + } finally {
  646 + IOUtils.closeQuietly(workbook);
  647 + }
  648 +
  649 + } catch (FileNotFoundException e) {
  650 + throw new RuntimeException("模板文件不存在: templates/fundCoordinationTemplate.xlsx", e);
  651 + } catch (IOException e) {
  652 + throw new RuntimeException("无法读取模板文件: templates/fundCoordinationTemplate.xlsx", e);
  653 + }
  654 + } catch (Exception e) {
  655 + log.error("资金协调手续打印: {}", e.getMessage(), e);
  656 + throw e;
  657 + }
  658 + }
  659 +
  660 + /**
  661 + * 设置HTTP响应头
  662 + */
  663 + private void setupResponse(HttpServletResponse response, String fileName) throws IOException {
  664 + String encodedFileName = URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20");
  665 +
  666 + response.setContentType("application/vnd.ms-excel");
  667 + response.setCharacterEncoding("UTF-8");
  668 + response.setHeader("Content-Disposition", "attachment;filename=" + encodedFileName);
  669 + response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
  670 + }
  671 +
  672 + private void processTemplate(Workbook workbook, Map<String, Object> dataMap) {
  673 + Sheet sheet = workbook.getSheetAt(0);
  674 +
  675 + for (Row row : sheet) {
  676 + for (Cell cell : row) {
  677 + if (cell.getCellTypeEnum() == CellType.STRING) {
  678 + String cellValue = cell.getStringCellValue();
  679 + String newValue = replacePlaceholders(cellValue, dataMap);
  680 + if (!cellValue.equals(newValue)) {
  681 + cell.setCellValue(newValue);
  682 + }
  683 + }
  684 + }
  685 + }
  686 + }
  687 +
  688 + private String replacePlaceholders(String text, Map<String, Object> dataMap) {
  689 + if (text == null || text.isEmpty()) {
  690 + return text;
  691 + }
  692 +
  693 + String result = text;
  694 + for (Map.Entry<String, Object> entry : dataMap.entrySet()) {
  695 + String placeholder = "${" + entry.getKey() + "}";
  696 + String value = entry.getValue() != null ? entry.getValue().toString() : "";
  697 + // 将数据库中的 \n 转换为 Excel 识别的换行符
  698 + value = value.replace("\\n", "\n");
  699 +
  700 + result = result.replace(placeholder, value);
  701 + }
  702 +
  703 + for (Map.Entry<String, Object> entry : dataMap.entrySet()) {
  704 + String placeholder = "#{" + entry.getKey() + "}";
  705 + String value = entry.getValue() != null ? entry.getValue().toString() : "";
  706 + // 将数据库中的 \n 转换为 Excel 识别的换行符
  707 + value = value.replace("\\n", "\n");
  708 +
  709 + result = result.replace(placeholder, value);
  710 + }
  711 +
  712 + return result;
  713 + }
  714 +
  715 + /**
  716 + * 处理订货单位及其应收款明细的动态插入
  717 + */
  718 + private void processOrderingUnits(Workbook workbook, Sheet sheet, List<FundOrderingUnit> unitList) {
  719 + if (CollectionUtils.isEmpty(unitList)) {
  720 + return;
  721 + }
  722 +
  723 + // 获取模板中的参考行(Excel 行号:第8行=索引7,第9行=索引8,第10行=索引9)
  724 +
  725 + // 从第10行开始写入
  726 + int startRow = 9; // 对应 Excel 第10行
  727 +
  728 + DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
  729 +
  730 + SysDataDicItemService sysDataDicItemService = ApplicationUtil.getBean(SysDataDicItemService.class);
  731 + List<SysDataDicItem> supplier = sysDataDicItemService.findByDicCode("REMARK");
  732 + Map<String, String> codeNameMap = supplier.stream()
  733 + .collect(Collectors.toMap(
  734 + SysDataDicItem::getCode,
  735 + SysDataDicItem::getName,
  736 + (e, r) -> e
  737 + ));
  738 + for (int j = 0; j < unitList.size(); j++) {
  739 + FundOrderingUnit unit = unitList.get(j);
  740 +
  741 + if (CollectionUtils.isEmpty(unit.getFundOrderingUnitDetailList())) {
  742 + continue;
  743 + }
  744 + if (j == 0) {
  745 + // === 3. 明细数据行 ===
  746 + for (int i = startRow + 1; i < startRow + unit.getFundOrderingUnitDetailList().size(); i++) {
  747 + copyRow(workbook, sheet, startRow, i);
  748 + }
  749 + setCellValue(sheet, 7, 0, unit.getOrderingUnitName() + "--应收款明细");
  750 + for (FundOrderingUnitDetail detail : unit.getFundOrderingUnitDetailList()) {
  751 + // 填充具体值(列索引根据你的模板调整)
  752 + setCellValue(sheet, startRow, 0, detail.getDeliveryDate() == null ? "" : detail.getDeliveryDate().format(dateFormatter));
  753 + setCellValue(sheet, startRow, 1, detail.getAccountsReceivable());
  754 + setCellValue(sheet, startRow, 2, detail.getStatus());
  755 + setCellValue(sheet, startRow, 3, detail.getDueDate() == null ? "" : detail.getDueDate().format(dateFormatter));
  756 + setCellValue(sheet, startRow, 4, detail.getTimeout());
  757 + setCellValue(sheet, startRow, 5, detail.getCoordinateHandleDate() == null ? "" : detail.getCoordinateHandleDate().format(dateFormatter));
  758 + setCellValue(sheet, startRow, 6, detail.getActualTimeout());
  759 + setCellValue(sheet, startRow, 7, detail.getRemark() == null ? "" : codeNameMap.get(detail.getRemark()));
  760 + startRow++;
  761 + }
  762 + if (StringUtils.isNotEmpty(unit.getRemark())) {
  763 + copyRow(workbook, sheet, 9, startRow);
  764 + // 合并 A-H 列
  765 + CellRangeAddress mergeRegion = new CellRangeAddress(startRow, startRow, 1, 7);
  766 + // 清空该行所有单元格的值(列范围可根据需要调整,比如 A~H 或整行)
  767 + Row targetRow1 = sheet.getRow(startRow);
  768 + if (targetRow1 != null) {
  769 + // 假设你只关心 A~H 列(列索引 0 ~ 7)
  770 + for (int colIndex = 0; colIndex <= 7; colIndex++) {
  771 + Cell cell = targetRow1.getCell(colIndex);
  772 + if (cell != null) {
  773 + cell.setCellValue((String) null); // 清空内容,保留样式
  774 + }
  775 + }
  776 + }
  777 + removeMergedRegionIfExists(sheet, mergeRegion);
  778 + sheet.addMergedRegion(mergeRegion);
  779 + //填充值
  780 + setCellValue(sheet, startRow, 0, "备注说明");
  781 + setCellValue(sheet, startRow, 1, unit.getRemark());
  782 + startRow++;
  783 + }
  784 + } else {
  785 + copyRow(workbook, sheet, 7, startRow);
  786 + // 合并 A-H 列
  787 + CellRangeAddress mergeRegion = new CellRangeAddress(startRow, startRow, 0, 7);
  788 + // 清空该行所有单元格的值(列范围可根据需要调整,比如 A~H 或整行)
  789 + Row targetRow1 = sheet.getRow(startRow);
  790 + if (targetRow1 != null) {
  791 + // 假设你只关心 A~H 列(列索引 0 ~ 7)
  792 + for (int colIndex = 0; colIndex <= 7; colIndex++) {
  793 + Cell cell = targetRow1.getCell(colIndex);
  794 + if (cell != null) {
  795 + cell.setCellValue((String) null); // 清空内容,保留样式
  796 + }
  797 + }
  798 + }
  799 + //填充值
  800 + setCellValue(sheet, startRow, 0, unit.getOrderingUnitName() + "--应收款明细");
  801 + removeMergedRegionIfExists(sheet, mergeRegion);
  802 + sheet.addMergedRegion(mergeRegion);
  803 + copyRow(workbook, sheet, 8, startRow + 1);
  804 + copyRow(workbook, sheet, 9, startRow + 2);
  805 + // 清空该行所有单元格的值(列范围可根据需要调整,比如 A~H 或整行)
  806 + Row targetRow = sheet.getRow(startRow + 2);
  807 + if (targetRow != null) {
  808 + // 假设你只关心 A~H 列(列索引 0 ~ 7)
  809 + for (int colIndex = 0; colIndex <= 7; colIndex++) {
  810 + Cell cell = targetRow.getCell(colIndex);
  811 + if (cell != null) {
  812 + cell.setCellValue((String) null); // 清空内容,保留样式
  813 + }
  814 + }
  815 + }
  816 + startRow = startRow + 2;
  817 + // === 3. 明细数据行 ===
  818 + for (int i = startRow + 1; i < startRow + unit.getFundOrderingUnitDetailList().size(); i++) {
  819 + copyRow(workbook, sheet, startRow, i);
  820 + }
  821 + for (FundOrderingUnitDetail detail : unit.getFundOrderingUnitDetailList()) {
  822 + // 填充具体值(列索引根据你的模板调整)
  823 + setCellValue(sheet, startRow, 0, detail.getDeliveryDate() == null ? "" : detail.getDeliveryDate().format(dateFormatter));
  824 + setCellValue(sheet, startRow, 1, detail.getAccountsReceivable());
  825 + setCellValue(sheet, startRow, 2, detail.getStatus());
  826 + setCellValue(sheet, startRow, 3, detail.getDueDate() == null ? "" : detail.getDueDate().format(dateFormatter));
  827 + setCellValue(sheet, startRow, 4, detail.getTimeout());
  828 + setCellValue(sheet, startRow, 5, detail.getCoordinateHandleDate() == null ? "" : detail.getCoordinateHandleDate().format(dateFormatter));
  829 + setCellValue(sheet, startRow, 6, detail.getActualTimeout());
  830 + setCellValue(sheet, startRow, 7, detail.getRemark() == null ? "" : codeNameMap.get(detail.getRemark()));
  831 + startRow++;
  832 + }
  833 + if (StringUtils.isNotEmpty(unit.getRemark())) {
  834 + copyRow(workbook, sheet, 9, startRow);
  835 + // 合并 B-H 列
  836 + CellRangeAddress mergeRegion1 = new CellRangeAddress(startRow, startRow, 1, 7);
  837 + // 清空该行所有单元格的值(列范围可根据需要调整,比如 A~H 或整行)
  838 + Row targetRow2 = sheet.getRow(startRow);
  839 + if (targetRow2 != null) {
  840 + // 假设你只关心 A~H 列(列索引 0 ~ 7)
  841 + for (int colIndex = 0; colIndex <= 7; colIndex++) {
  842 + Cell cell = targetRow2.getCell(colIndex);
  843 + if (cell != null) {
  844 + cell.setCellValue((String) null); // 清空内容,保留样式
  845 + }
  846 + }
  847 + }
  848 + removeMergedRegionIfExists(sheet, mergeRegion1);
  849 + sheet.addMergedRegion(mergeRegion1);
  850 + //填充值
  851 + setCellValue(sheet, startRow, 0, "备注说明");
  852 + setCellValue(sheet, startRow, 1, unit.getRemark());
  853 + startRow++;
  854 + }
  855 + }
  856 + }
  857 +
  858 + }
  859 +
  860 + // ===== 辅助方法 =====
  861 +
  862 + /**
  863 + * 复制行并处理合并单元格
  864 + */
  865 + public static void copyRow(Workbook workbook, Sheet sheet,
  866 + int sourceRowIndex, int targetRowIndex) {
  867 +
  868 + // 获取源行的所有合并区域
  869 +// List<CellRangeAddress> mergedRegions = getMergedRegionsInRow(sheet, sourceRowIndex);
  870 +
  871 + // 移动目标行及之后的行
  872 + if (targetRowIndex <= sheet.getLastRowNum()) {
  873 + sheet.shiftRows(targetRowIndex, sheet.getLastRowNum(), 1, true, false);
  874 + }
  875 +
  876 + // 复制行内容
  877 + Row sourceRow = sheet.getRow(sourceRowIndex);
  878 + Row newRow = sheet.createRow(targetRowIndex);
  879 + newRow.setHeight(sourceRow.getHeight());
  880 +
  881 + // 复制单元格
  882 + for (int i = 0; i < sourceRow.getLastCellNum(); i++) {
  883 + Cell oldCell = sourceRow.getCell(i);
  884 + Cell newCell = newRow.createCell(i);
  885 +
  886 + if (oldCell != null) {
  887 + copyCell(workbook, oldCell, newCell);
  888 + }
  889 + }
  890 +
  891 + // 处理合并单元格
  892 +// handleMergedRegions(sheet, mergedRegions, sourceRowIndex, targetRowIndex);
  893 + }
  894 +
  895 + /**
  896 + * 获取行中涉及的合并区域
  897 + */
  898 + private static List<CellRangeAddress> getMergedRegionsInRow(Sheet sheet, int rowIndex) {
  899 + List<CellRangeAddress> result = new ArrayList<>();
  900 + for (int i = 0; i < sheet.getNumMergedRegions(); i++) {
  901 + CellRangeAddress mergedRegion = sheet.getMergedRegion(i);
  902 + if (mergedRegion.getFirstRow() == rowIndex) {
  903 + result.add(mergedRegion);
  904 + }
  905 + }
  906 + return result;
  907 + }
  908 +
  909 + /**
  910 + * 处理合并单元格的复制
  911 + */
  912 + private static void handleMergedRegions(Sheet sheet, List<CellRangeAddress> mergedRegions,
  913 + int sourceRowIndex, int targetRowIndex) {
  914 +
  915 + for (CellRangeAddress oldRegion : mergedRegions) {
  916 + // 创建新的合并区域
  917 + CellRangeAddress newRegion = new CellRangeAddress(
  918 + targetRowIndex,
  919 + targetRowIndex + (oldRegion.getLastRow() - oldRegion.getFirstRow()),
  920 + oldRegion.getFirstColumn(),
  921 + oldRegion.getLastColumn()
  922 + );
  923 +
  924 + sheet.addMergedRegion(newRegion);
  925 +
  926 + // 设置合并区域的边框样式
  927 + setMergedRegionBorderStyle(sheet, newRegion);
  928 + }
  929 + }
  930 +
  931 +
  932 + /**
  933 + * 设置合并单元格的边框样式
  934 + */
  935 + private static void setMergedRegionBorderStyle(Sheet sheet, CellRangeAddress region) {
  936 + Row firstRow = sheet.getRow(region.getFirstRow());
  937 + if (firstRow != null) {
  938 + Cell firstCell = firstRow.getCell(region.getFirstColumn());
  939 + if (firstCell != null && firstCell.getCellStyle() != null) {
  940 + CellStyle style = firstCell.getCellStyle();
  941 +
  942 + // 为合并区域的所有单元格设置样式
  943 + for (int i = region.getFirstRow(); i <= region.getLastRow(); i++) {
  944 + Row row = sheet.getRow(i);
  945 + if (row == null) {
  946 + row = sheet.createRow(i);
  947 + }
  948 + for (int j = region.getFirstColumn(); j <= region.getLastColumn(); j++) {
  949 + Cell cell = row.getCell(j);
  950 + if (cell == null) {
  951 + cell = row.createCell(j);
  952 + }
  953 + cell.setCellStyle(style);
  954 + }
  955 + }
  956 + }
  957 + }
  958 + }
  959 +
  960 +
  961 + /**
  962 + * 复制单元格内容和样式
  963 + */
  964 + private static void copyCell(Workbook workbook, Cell oldCell, Cell newCell) {
  965 + if (oldCell.getCellStyle() != null) {
  966 + newCell.setCellStyle(oldCell.getCellStyle());
  967 + }
  968 +
  969 + switch (oldCell.getCellTypeEnum()) {
  970 + case STRING:
  971 + newCell.setCellValue(oldCell.getStringCellValue());
  972 + break;
  973 + case NUMERIC:
  974 + newCell.setCellValue(oldCell.getNumericCellValue());
  975 + break;
  976 + case BOOLEAN:
  977 + newCell.setCellValue(oldCell.getBooleanCellValue());
  978 + break;
  979 + case FORMULA:
  980 + newCell.setCellFormula(oldCell.getCellFormula());
  981 + break;
  982 + default:
  983 + newCell.setCellValue(oldCell.getStringCellValue());
  984 + break;
  985 + }
  986 + }
  987 +
  988 + /**
  989 + * 设置单元格值
  990 + */
  991 + private static void setCellValue(Sheet sheet, int rowNum, int colNum, Object value) {
  992 + Row row = sheet.getRow(rowNum);
  993 + if (row == null) {
  994 + row = sheet.createRow(rowNum);
  995 + }
  996 +
  997 + Cell cell = row.getCell(colNum);
  998 + if (cell == null) {
  999 + cell = row.createCell(colNum);
  1000 + }
  1001 +
  1002 + if (value == null) {
  1003 + cell.setCellValue("");
  1004 + } else if (value instanceof String) {
  1005 + cell.setCellValue((String) value);
  1006 + } else if (value instanceof Integer) {
  1007 + cell.setCellValue((Integer) value);
  1008 + } else if (value instanceof Double) {
  1009 + cell.setCellValue((Double) value);
  1010 + } else if (value instanceof BigDecimal) {
  1011 + cell.setCellValue(((BigDecimal) value).doubleValue());
  1012 + } else if (value instanceof LocalDate) {
  1013 + cell.setCellValue(((LocalDate) value).format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
  1014 + }
  1015 + }
  1016 +
  1017 +// private void removeMergedRegionIfExists(Sheet sheet, CellRangeAddress newRegion) {
  1018 +// for (int i = sheet.getNumMergedRegions() - 1; i >= 0; i--) {
  1019 +// CellRangeAddress existing = sheet.getMergedRegion(i);
  1020 +// if (existing.intersects(newRegion)) {
  1021 +// sheet.removeMergedRegion(i);
  1022 +// }
  1023 +// }
  1024 +// }
  1025 +
  1026 + private void removeMergedRegionIfExists(Sheet sheet, CellRangeAddress target) {
  1027 + List<CellRangeAddress> mergedRegions = sheet.getMergedRegions();
  1028 + for (int i = mergedRegions.size() - 1; i >= 0; i--) {
  1029 + CellRangeAddress existing = mergedRegions.get(i);
  1030 + if (existing.equals(target)) {
  1031 + sheet.removeMergedRegion(i);
  1032 + break;
  1033 + }
  1034 + }
  1035 + }
  1036 +
  1037 + private CellStyle createTitleStyle(Workbook wb) {
  1038 + CellStyle style = wb.createCellStyle();
  1039 + Font font = wb.createFont();
  1040 + font.setBold(true);
  1041 + font.setFontHeightInPoints((short) 11);
  1042 + style.setFont(font);
  1043 + style.setAlignment(HorizontalAlignment.LEFT);
  1044 + style.setFillForegroundColor(IndexedColors.LIGHT_BLUE.getIndex());
  1045 + style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
  1046 + return style;
  1047 + }
  1048 +
  1049 + private CellStyle createHeaderStyle(Workbook wb) {
  1050 + CellStyle style = wb.createCellStyle();
  1051 + Font font = wb.createFont();
  1052 + font.setBold(true);
  1053 + style.setFont(font);
  1054 + style.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
  1055 + style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
  1056 + style.setBorderTop(BorderStyle.THIN);
  1057 + style.setBorderBottom(BorderStyle.THIN);
  1058 + style.setBorderLeft(BorderStyle.THIN);
  1059 + style.setBorderRight(BorderStyle.THIN);
  1060 + return style;
  1061 + }
  1062 +
  1063 + private CellStyle createBoldLeftStyle(Workbook wb) {
  1064 + CellStyle style = wb.createCellStyle();
  1065 + Font font = wb.createFont();
  1066 + font.setBold(true);
  1067 + style.setFont(font);
  1068 + style.setAlignment(HorizontalAlignment.LEFT);
  1069 + return style;
  1070 + }
  1071 +
  1072 + private CellStyle createContentStyle(Workbook wb) {
  1073 + CellStyle style = wb.createCellStyle();
  1074 + style.setAlignment(HorizontalAlignment.LEFT);
  1075 + return style;
  1076 + }
516 1077 }
... ...
... ... @@ -183,7 +183,7 @@ public class FundCoordinationServiceImpl extends BaseMpServiceImpl<FundCoordinat
183 183 //审核
184 184 String deptCode = transactorHandler.returnDeptCode(SecurityUtil.getCurrentUser().getId());
185 185 data.setDeptCode(deptCode);
186   -// flowInstanceWrapperService.startInstance(BPM_FLAG, data.getId(), BPM_FLAG, data);
  186 + flowInstanceWrapperService.startInstance(BPM_FLAG, data.getId(), BPM_FLAG, data);
187 187 return data.getId();
188 188 }
189 189
... ...