diff --git a/bms-back/bms-system/src/main/java/com/bms/ar/service/impl/ArBillServiceImpl.java b/bms-back/bms-system/src/main/java/com/bms/ar/service/impl/ArBillServiceImpl.java index 48d831d6..8b095eef 100644 --- a/bms-back/bms-system/src/main/java/com/bms/ar/service/impl/ArBillServiceImpl.java +++ b/bms-back/bms-system/src/main/java/com/bms/ar/service/impl/ArBillServiceImpl.java @@ -1570,6 +1570,8 @@ public class ArBillServiceImpl implements IArBillService { private void writeOoxmlFooter(OutputStream output, Map templateRows, int footerRow, ArBill bill) throws IOException { int rowOffset = footerRow - TEMPLATE_FOOTER_START_ROW; + int lastDetailRow = Math.max(TEMPLATE_DATA_START_ROW, footerRow - 1); + String totalAmountFormula = "SUM(S" + TEMPLATE_DATA_START_ROW + ":S" + lastDetailRow + ")"; for (int offset = 0; offset < 4; offset++) { int sourceRowNumber = TEMPLATE_FOOTER_START_ROW + offset + 1; int targetRowNumber = sourceRowNumber + rowOffset; @@ -1577,7 +1579,8 @@ public class ArBillServiceImpl implements IArBillService { if (offset == 0) { row = replaceCellXml(row, "B" + targetRowNumber, "银行信息", false); row = replaceCellXml(row, "P" + targetRowNumber, "本期应收金额", false); - row = replaceCellXml(row, "S" + targetRowNumber, bill.getTotalAmount(), true); + row = replaceFormulaCellXml(row, "S" + targetRowNumber, totalAmountFormula, + nvl(bill.getTotalAmount())); } else if (offset == 1) { row = replaceCellXml(row, "B" + targetRowNumber, "开户名", false); row = replaceCellXml(row, "C" + targetRowNumber, bill.getBankAccountName(), false); @@ -1587,7 +1590,9 @@ public class ArBillServiceImpl implements IArBillService { row = replaceCellXml(row, "B" + targetRowNumber, "账号", false); row = replaceCellXml(row, "C" + targetRowNumber, exportBankAccountNo(bill.getBankAccountNo()), false); row = replaceCellXml(row, "P" + targetRowNumber, "本期未核销金额", false); - row = replaceCellXml(row, "S" + targetRowNumber, bill.getUnwrittenAmount(), true); + String unwrittenAmountFormula = "S" + (targetRowNumber - 2) + "-S" + (targetRowNumber - 1); + row = replaceFormulaCellXml(row, "S" + targetRowNumber, unwrittenAmountFormula, + nvl(bill.getUnwrittenAmount())); } else { row = replaceCellXml(row, "B" + targetRowNumber, "开户行", false); row = replaceCellXml(row, "C" + targetRowNumber, bill.getBankName(), false); @@ -1675,6 +1680,16 @@ public class ArBillServiceImpl implements IArBillService { } private String replaceCellXml(String rowXml, String reference, Object value, boolean numeric) throws IOException { + return replaceCellXml(rowXml, reference, value, numeric, null); + } + + private String replaceFormulaCellXml(String rowXml, String reference, String formula, Number cachedValue) + throws IOException { + return replaceCellXml(rowXml, reference, cachedValue, true, formula); + } + + private String replaceCellXml(String rowXml, String reference, Object value, boolean numeric, String formula) + throws IOException { if (rowXml == null) { throw new IOException("应收账单模板缺少行: " + reference); } @@ -1694,6 +1709,9 @@ public class ArBillServiceImpl implements IArBillService { StringBuilder cell = new StringBuilder(""); if (numeric) { + if (formula != null) { + cell.append("").append(xmlEscape(formula)).append(""); + } cell.append("").append(value == null ? "" : numberText((Number) value)).append(""); } else { String text = value == null ? "" : String.valueOf(value); @@ -1708,7 +1726,7 @@ public class ArBillServiceImpl implements IArBillService { } matcher.appendTail(result); if (!found) { - return insertMissingCellXml(rowXml, reference, value, numeric); + return insertMissingCellXml(rowXml, reference, value, numeric, formula); } return result.toString(); } @@ -1717,7 +1735,8 @@ public class ArBillServiceImpl implements IArBillService { * 兼容不同 Excel/WPS 版本保存后被省略的空单元格,按列顺序补回动态单元格。 * C3/P3 使用模板中对应的样式,避免客户名称或账单周期单元格变成无边框样式。 */ - private String insertMissingCellXml(String rowXml, String reference, Object value, boolean numeric) throws IOException { + private String insertMissingCellXml(String rowXml, String reference, Object value, boolean numeric, String formula) + throws IOException { int rowEnd = rowXml.lastIndexOf(""); if (rowEnd < 0) { throw new IOException("应收账单模板缺少行结束节点: " + reference); @@ -1739,9 +1758,11 @@ public class ArBillServiceImpl implements IArBillService { cell.append(" s=\"").append(style).append("\""); } if (numeric) { - cell.append(" t=\"n\">") - .append(value == null ? "" : numberText((Number) value)) - .append(""); + cell.append(" t=\"n\">"); + if (formula != null) { + cell.append("").append(xmlEscape(formula)).append(""); + } + cell.append("").append(value == null ? "" : numberText((Number) value)).append(""); } else { String text = value == null ? "" : String.valueOf(value); cell.append(" t=\"inlineStr\">