This commit is contained in:
haomingming 2026-01-04 14:15:19 +08:00
parent 3a7c6aa4e3
commit e4b4423b66

View File

@ -18,6 +18,7 @@ public class CustomExcelWriteHandler implements WriteHandler {
private final double totalTotal; private final double totalTotal;
private final int dataSize; private final int dataSize;
private boolean totalRowCreated = false; private boolean totalRowCreated = false;
private int processedDataRowCount = 0; // 已处理的数据行数
// 缓存 Workbook afterSheetCreate 中初始化 // 缓存 Workbook afterSheetCreate 中初始化
private Workbook workbook; private Workbook workbook;
@ -64,82 +65,96 @@ public class CustomExcelWriteHandler implements WriteHandler {
headRow.setHeightInPoints(25); headRow.setHeightInPoints(25);
} }
// 关键数据行写入完成后创建合计行兼容低版本 // 设置数据行行高并在最后一行数据写入后创建合计行
public void afterRowDispose(WriteSheetHolder writeSheetHolder, Row row, Integer relativeRowIndex, Boolean isHead) throws IOException { public void afterRowDispose(WriteSheetHolder writeSheetHolder, Row row, Integer relativeRowIndex, Boolean isHead) throws IOException {
// 仅在最后一行数据写入后创建合计行且未创建过 // 设置数据行行高排除表头行
if (!totalRowCreated && relativeRowIndex != null && relativeRowIndex == dataSize - 1) { if (isHead == null || !isHead) {
Sheet sheet = writeSheetHolder.getSheet(); processedDataRowCount++;
if (row.getRowNum() >= 2 && row.getRowNum() <= 1 + dataSize) {
// 修正合计行索引0=大标题1=表头2~1+dataSize=数据2+dataSize=合计 row.setHeightInPoints(22);
int totalRowIndex = 2 + dataSize;
Row totalRow = sheet.createRow(totalRowIndex);
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 < 14; 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);
} }
// 标记合计行已创建 // 如果是最后一行数据创建合计行
totalRowCreated = true; if (!totalRowCreated && processedDataRowCount == dataSize && dataSize > 0) {
createTotalRow(writeSheetHolder.getSheet());
// 强制刷新兼容SXSSF
if (sheet instanceof SXSSFSheet) {
((SXSSFSheet) sheet).flushRows();
} }
} }
}
// 设置数据行行高 // 创建合计行的辅助方法
if (row.getRowNum() >= 2 && row.getRowNum() <= 1 + dataSize) { private void createTotalRow(Sheet sheet) throws IOException {
row.setHeightInPoints(22); // 修正合计行索引0=大标题1=表头2~1+dataSize=数据2+dataSize=合计
int totalRowIndex = 2 + dataSize;
Row totalRow = sheet.createRow(totalRowIndex);
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 < 14; 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);
}
// 标记合计行已创建
totalRowCreated = true;
// 强制刷新兼容SXSSF
if (sheet instanceof SXSSFSheet) {
((SXSSFSheet) sheet).flushRows();
}
}
// 备用在所有数据写入完成后创建合计行如果 afterRowDispose 中没有创建
public void afterSheetDispose(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) throws IOException {
// 如果合计行还未创建则创建备用方案
if (!totalRowCreated && dataSize > 0) {
createTotalRow(writeSheetHolder.getSheet());
} }
} }