diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcase/controller/CaseplatformCaseExcelController.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcase/controller/CaseplatformCaseExcelController.java index 9f4fff3..6d76652 100644 --- a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcase/controller/CaseplatformCaseExcelController.java +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcase/controller/CaseplatformCaseExcelController.java @@ -18,6 +18,8 @@ import net.lab1024.sa.common.common.exception.BusinessException; import net.lab1024.sa.common.module.support.operatelog.annoation.OperateLog; import org.apache.poi.ss.formula.functions.T; import org.apache.poi.ss.usermodel.*; +import org.apache.poi.ss.util.CellRangeAddress; +import org.apache.poi.xssf.streaming.SXSSFSheet; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; @@ -157,6 +159,101 @@ public class CaseplatformCaseExcelController { // 写数据 writer.write(processedList, writeSheet); + // 创建合计行(在数据写入后,finish 之前) + try { + Workbook workbook = writer.writeContext().writeWorkbookHolder().getWorkbook(); + Sheet sheet = workbook.getSheetAt(0); + int totalRowIndex = 2 + processedList.size(); // 0=大标题,1=表头,2~1+size=数据,2+size=合计 + + Row totalRow = null; + // 如果是 SXSSFSheet,需要特殊处理 + if (sheet instanceof SXSSFSheet) { + SXSSFSheet sxssfSheet = (SXSSFSheet) sheet; + // 先刷新所有已写入的行到磁盘 + sxssfSheet.flushRows(); + // 然后尝试创建新行 + try { + totalRow = sxssfSheet.createRow(totalRowIndex); + } catch (IllegalArgumentException e) { + // 如果行已经存在,尝试获取它 + totalRow = sxssfSheet.getRow(totalRowIndex); + if (totalRow == null) { + // 如果获取失败,尝试使用随机访问窗口 + sxssfSheet.setRandomAccessWindowSize(-1); // 禁用随机访问窗口限制 + totalRow = sxssfSheet.createRow(totalRowIndex); + } + } + } else { + // 普通 Sheet,直接创建或获取 + totalRow = sheet.getRow(totalRowIndex); + if (totalRow == null) { + totalRow = sheet.createRow(totalRowIndex); + } + } + + if (totalRow == null) { + throw new RuntimeException("无法创建合计行"); + } + + totalRow.setHeightInPoints(22); + + // 合计行样式(黑底白字) + CellStyle totalStyle = workbook.createCellStyle(); + Font totalFont = workbook.createFont(); + totalFont.setBold(true); + totalFont.setColor(IndexedColors.WHITE.getIndex()); + totalStyle.setFont(totalFont); + totalStyle.setFillForegroundColor(IndexedColors.BLACK.getIndex()); + totalStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); + totalStyle.setAlignment(HorizontalAlignment.CENTER); + totalStyle.setVerticalAlignment(VerticalAlignment.CENTER); + totalStyle.setBorderTop(BorderStyle.THIN); + totalStyle.setBorderBottom(BorderStyle.THIN); + totalStyle.setBorderLeft(BorderStyle.THIN); + totalStyle.setBorderRight(BorderStyle.THIN); + + // 合并前6列写"合计" + sheet.addMergedRegion(new CellRangeAddress(totalRowIndex, totalRowIndex, 0, 5)); + Cell totalCell = totalRow.createCell(0); + totalCell.setCellValue("合计"); + totalCell.setCellStyle(totalStyle); + + // 实发、个税、应发赋值+样式 + Cell actualCell = totalRow.createCell(6); + actualCell.setCellValue(totalActual); + actualCell.setCellStyle(totalStyle); + + Cell taxCell = totalRow.createCell(8); + taxCell.setCellValue(totalTax); + taxCell.setCellStyle(totalStyle); + + Cell totalAmtCell = totalRow.createCell(9); + totalAmtCell.setCellValue(totalTotal); + totalAmtCell.setCellStyle(totalStyle); + + // 其他列补充边框 + CellStyle borderStyle = workbook.createCellStyle(); + borderStyle.setBorderBottom(BorderStyle.THIN); + borderStyle.setBorderTop(BorderStyle.THIN); + borderStyle.setBorderLeft(BorderStyle.THIN); + borderStyle.setBorderRight(BorderStyle.THIN); + borderStyle.setAlignment(HorizontalAlignment.CENTER); + + for (int i = 0; i < head.size(); i++) { + if (i == 0 || i == 6 || i == 8 || i == 9) { + continue; + } + Cell cell = totalRow.getCell(i); + if (cell == null) { + cell = totalRow.createCell(i); + } + cell.setCellStyle(borderStyle); + } + } catch (Exception e) { + // 如果创建合计行失败,记录错误但不影响导出 + e.printStackTrace(); + } + // 6通知浏览器以附件的形式下载处理,设置返回头要注意文件名有中文 String fileName = URLEncoder.encode("病例数据", "UTF-8").replaceAll("\\+", "%20"); response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");