| HANDOFF.md | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| traffic-audit-server/src/main/java/com/trafficaudit/reportexport/layout/SummaryLayoutExpander.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
HANDOFF.md
@@ -64,6 +64,13 @@ - **一处需用户拍板的数值变化**:本次生成件 `中口径排名` 有 **46 格**(同比/排名,如 `D3` 0.0581→**0.0402**、`E4` 第10→第**9**)与上一版不同;**新值与《中口径分析》页逐位一致**(`B3=35028.0636`、`C3=0.04015856`)——即排名页与明细/分析页口径统一(原旧值是该页在母版里的旧缓存)。**保留新值 / 回退旧值待用户确认**。 - **归档说明**:`归档/` 内 5 件历史母版/版式件仍可随时取回(未删除);母版目录以后只放"当期一本"。 - **状态**:**【待验收】**。 ### 10-12(9):扩列器加「整本重算写缓存」+ 明确保留中口径排名新值【待验收】 - **问题定位(用户问"为什么产生这 46 格差异")**:母版里**大量公式只有公式、没有缓存值**(POI 写公式不带缓存)。实证:母版经 Excel 保存前后 **约 2.47 万格**由"空"变"有值"(如 ` 货运!U5: 空→130311.8927`)。`中口径排名` 的同比/排名由程序**读母版缓存**计算(方案 A)→ 缓存空时算旧值 `0.0581`,缓存补齐后算 `0.0402`(**与《中口径分析》逐位一致**)。**新值才是数据完整时的正确结果**。 - **改动**:`SummaryLayoutExpander` 新增 `recalcAndCache(wb)`(`clearAllCachedResultValues()` + `evaluateAll()` 写回缓存,失败仅 WARN),在 `expand()` 与 `fixTitles()` 中调用。 - **验证**:扩列 2026-08 → 公式格 **39,961** 个,**空缓存仅 4 格**(全在 ` 货运`,POI 无法求解的外部引用,Excel 打开会算);修复前同类母版约 2.47 万格无缓存。 - **用户决定**:`中口径排名` 那 46 格**保留新值**(与中口径分析一致,口径统一)。 - **报告(本地、不入库)**:`docs/功能测试报告/功能测试报告_扩列整本重算写缓存_2026-10-12.md`。状态:**【待验收】**。 ## 最新(2026-10-12,zyj 线) ### 10-12:扩列器补「标题按母版期次重写」+ 修正 8 月母版标题【待验收】 traffic-audit-server/src/main/java/com/trafficaudit/reportexport/layout/SummaryLayoutExpander.java
@@ -3,6 +3,7 @@ import lombok.extern.slf4j.Slf4j; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellType; import org.apache.poi.ss.usermodel.FormulaEvaluator; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.util.CellRangeAddress; @@ -80,6 +81,7 @@ if (sh == null || expanded.contains(sh.getSheetName())) continue; shiftQualifiedRefs(sh, insertColOf); } recalcAndCache(wb); int titleFixed = applyTitles(wb, year, targetMonth); if (titleFixed > 0) { log.info("扩列:标题按 {}年{}月 重写 {} 格", year, targetMonth, titleFixed); @@ -96,6 +98,7 @@ /** 只把 7 个标题页的标题按给定期次重写(用于修正母版里滞后的标题)。 */ public byte[] fixTitles(byte[] source, int year, int month) { try (XSSFWorkbook wb = new XSSFWorkbook(new ByteArrayInputStream(source))) { recalcAndCache(wb); int n = applyTitles(wb, year, month); wb.setForceFormulaRecalculation(true); ByteArrayOutputStream out = new ByteArrayOutputStream(); @@ -107,6 +110,17 @@ } } /** 整本重算并把结果写入缓存值:否则母版里只有公式没有值,后续读取会把空值当 0(2026-10-12 修) */ private void recalcAndCache(XSSFWorkbook wb) { try { FormulaEvaluator ev = wb.getCreationHelper().createFormulaEvaluator(); ev.clearAllCachedResultValues(); ev.evaluateAll(); } catch (Exception e) { log.warn("扩列:整本重算未完成(公式仍在,Excel 打开会再算):{}", e.getMessage()); } } /** 把 7 个页签的标题文字按「累计=1-M月、当月=M月」重写;命中标记才改,避免误伤备注。 */ private int applyTitles(XSSFWorkbook wb, int year, int month) { int changed = 0;