用户反馈:导出 2026 年 8 月《道路运输量汇总表》后,以下 4 张**跨页合成页**仍是上一报表期的静态值(标题写「2026年1-7月 / 2026年7月」,数值也是 7 月的,不随报表期变化):
| 页名 | 母版原状态 |
|---|---|
城市汇总 |
整页静态(1-7 月累计 + 7 月当月) |
城市分市州 |
4 块整页静态 |
中口径分析 |
2 块整页静态 |
道路运输周转量 |
2 块整页静态 |
用户选定**方案 A**:沿用货运排名页的做法——用母版台账页自带的 2025 年同期列缓存值当同比基数,把「当年累计值」刷成 1-8 月(同比列沿用母版口径),4 页一次性做出来。
编码前先用母版台账页逐格聚合反推四页口径,与四页成品逐格比对 0 差异后确认:
| 指标 | 口径 |
|---|---|
| 城市客运量 | 公交城市内客运量 + 巡游出租城市内客运量 + 网约车城市内客运量 + 轨道客运量 + 轮渡客运量 |
| 城市客运周转量 | 同上,换成各自旅客周转量 |
| 中口径客运量/周转量 | 公路班线包车 + 城际城乡公交 + 城际城乡巡游出租 + 城际城乡网约车,其中「城际城乡 X = X 总量 − X 城市内」(仅公交/出租/网约车;班线包车无城市内概念,直接用总量) |
| 道路货运周转量 | 货运页市州「规上货物周转量 + 规下货物周转量」(**不用**母版「规上+规下」公式行) |
| 道路运输周转量页「道路客运周转量」 | 班线包车周转量 + 城际城乡公交/出租/网约车周转量 |
| 同比 | 当期 ÷ 母版台账页 2025 年同期列 − 1 |
关于 2025 同期基数:库中只有 2026 年城市客运/网约车数据,没有 2025 年数据,故 2025 同期一律取**母版台账页自带的 2025 年逐月列缓存值**(V=1月、X=2月 … AJ=8月)。这也正是方案 A 的取巧点:母版台账页本身带全 2025 逐月列,无需等 2025 数据入库。
改动文件:traffic-audit-server/src/main/java/com/trafficaudit/reportexport/service/ReportExportService.java(+494 −2)。
refreshSummaryCumulativeSheets(XSSFWorkbook wb, int year, int month);接在导出链路的 refreshSummaryRankSheets(...) 之后、applySummaryReferenceLayout(wb) 之前调用。smReadLedgerMetrics:**按行标签识别、不写死行号**公交/出租/网约车:每市州「客运量 / 旅客周转量 / 其中城市内客运量 / 其中城市内旅客周转量」4 行;轨道、轮渡:轨道(全省/武汉/黄石)与轮渡(全省/武汉)分块;班线包车:全省与 17 市州客运量/周转量(「其中个体」行不重复计入);货运(页名带前导空格):市州「规上货物周转量 + 规下货物周转量」。SM_CUR_COL0=2),2025 年同期列 V=1月 … AJ=8月(SM_LAST_COL0=21),每月间隔 2 列(值列 + 同比列)。SM_DIM=19):公交/出租/网约车 各 4 维(总量、周转量、城市内总量、城市内周转量)+ 轨道 2 维 + 轮渡 2 维 + 班线包车 2 维 + 货运周转量 1 维。smSetVal:**目标格原本是公式 → 保留母版公式不覆盖**(打开即重算);目标格为空且新值为 0 → 不新增;其余先 setBlank() 再写,避免 inlineStr 残留。http://localhost:8090(start-dev.ps1 启动,PID 27840),前端 http://localhost:8080(PID 23416)均就绪。docs/生成汇总大表/2026年8月道路运输量汇总表.xlsx;版式参照:docs/生成汇总大表/生成_道路运输量汇总表.xlsx。GET /api/report/export/summaryWorkbook?period=YYYY-MM(Bearer token)。_t3_2026-08.xlsx(950,783 字节 / HTTP 200 / 36.8 秒)、_t3_2026-07.xlsx(942,691 字节 / HTTP 200 / 25.7 秒);归档件 docs/生成汇总大表/输出/生成_道路运输量汇总表_2026-08_四页数据驱动_2026-09-13.xlsx(950,783 字节)。_v5_four.py(输出 _v5_four.txt)、_verify_four.py(输出 _verify_four.txt)。| 编号 | 输入 | 预期 | 实际 | 结论 |
|---|---|---|---|---|
| TC-1 | 导出 period=2026-08 |
HTTP 200,正常产出 | 950,783 字节,36.8 秒 | 通过 |
| TC-2 | 与 09-13 13:06 归档件比对 | 同参数导出结果确定 | 两次产物同为 950,783 字节 | 通过 |
| TC-3 | 后端回填日志 | 有四页刷新统计、无缺数提示、无异常 | 「刷新四页(城市汇总/城市分市州/中口径分析/道路运输周转量)数值格数=1056」「刷新排名页数值格数=711」「缺数提示=[]」;最近 4MB 日志无 ERROR/Exception/WARN |
通过 |
| TC-4 | 城市汇总 标题 |
随报表期改为 1-8 月 / 8 月 | A1=2026年1-8月全省累计完成城市客运量情况、A12=2026年8月全省完成城市客运量情况 |
通过 |
| TC-5 | 城市汇总 累计块(B3:E9) |
客运量/同比/周转量/同比 各 7 行 | 28 格全部一致(如 B3=269628.07、C3=0.00117、D3=1681467.65、E3=0.00835) | 通过 |
| TC-6 | 城市汇总 当月块(B14:E20) |
同上,当月口径 | 28 格全部一致(如 B14=32215.74、C14=0.0444) | 通过 |
| TC-7 | 城市分市州 标题 ×4 |
4 块标题随报表期 | A1=…1-8月累计情况、A23=…1-8月累计情况、A46=…8月情况、A68=…8月情况 |
通过 |
| TC-8 | 城市分市州 4 块 × 17 市州 × 6 值列 |
6 组值 = 总量/公交/出租/网约车/轨道/轮渡 | 408 格全部一致 | 通过 |
| TC-9 | 中口径分析 标题 + 数值 |
2 块标题 + 每块 总/班线/城乡公交/城乡出租/城乡网约车 | A1=1-8月中口径客运量及周转量、A10=8月中口径客运量及周转量;B3=31528.0607、F3=1227147.4890 等 10 格全部一致 |
通过 |
| TC-10 | 道路运输周转量 标题 + 数值 |
2 块标题 + 17 市州 G/L/Q/W/X/Y | A1=2026年1-8月全省累计完成交通周转量情况、A23=2026年8月全省完成交通周转量情况;102 格全部一致(如 G4=17492129.04788293、L4=269628.07、Q4=1227147.48902;W/X/Y 同期列取 2025 年同期累计,如 W4=17492068.4575、X4=269312.48、Y4=1256684.2157) |
通过 |
| 编号 | 输入 | 预期 | 实际 | 结论 |
|---|---|---|---|---|
| TC-N1 | 目标格是母版公式(城市分市州 全省行 B5=G5+L5+Q5+V5+X5、道路运输周转量 J4=G4/W4-1) |
不被写值覆盖,保留母版公式 | 两者仍为公式;四页写入格数 1056 < 四页理论格数,说明公式格被跳过 | 通过 |
| TC-N2 | 目标格为空且新值为 0 | 不新增 0,避免把成品页写成满页 0 | SM_货运 无数据的市州轨道/轮渡值未产生新增 0 格 |
通过 |
| TC-N3 | 2025 同期无库数据 | 取母版台账页 2025 列缓存,不出现 NaN/Inf | 同比全部为有限数(如 城市汇总 C7=0.4870、C14=0.0444) |
通过 |
| TC-N4 | 台账页读不到市州数据(极端情况) | 记 WARN 并**保持母版原值**、不写坏页 |
代码路径 curCum.isEmpty() → log.warn("…台账页未读到市州数据,跳过(保持母版原值)");本轮台账页数据齐全,未实际触发(**代码审查用例**) |
通过(审查) |
| TC-N5 | 母版标题为 inlineStr | 标题必须真正落盘更新,不能只改 <v> |
smSetTitle 先 setBlank() 再写,标题校验全部读取到新文案 |
通过 |
| 编号 | 输入 | 预期 | 实际 | 结论 |
|---|---|---|---|---|
| TC-R1 | 导出 period=2026-07 |
不崩,且四页应回退成「1-7 月」口径 | HTTP 200 / 942,691 字节 / 25.7 秒;标题 城市汇总 A1=2026年1-7月…、城市客运客运量分市州1-7月累计情况、1-7月中口径客运量及周转量、2026年1-7月全省累计完成交通周转量情况 |
通过 |
| TC-R2 | 2026-07 导出值 vs 母版 1-7 月静态权威值 | 应完全一致(证明口径与母版一致,只是随月份延长) | 城市汇总 B3=237412.33000000002(母版 237412.33)、中口径 B3=27524.4906、道路运输周转量 G4=15222118.44638293、城市分市州 B6=135474.77989442425 —— 与母版逐项一致 | 通过 |
| TC-R3 | 后端服务可用性 | 前端首页可访问 | http://localhost:8080/ HTTP 200,标题「交通统计报表审核系统」 |
通过 |
方法:从生成件**自身的台账页**重新聚合(不读库、不参考任何其它文件),再与四页逐格比对。
| 复核范围 | 格数 |
|---|---|
| 标题(城市汇总 2 + 城市分市州 4 + 中口径 2 + 道路运输周转量 2) | 10 |
| 城市汇总 累计块(7 行 × 客运量/同比/周转量/同比) | 28 |
| 城市汇总 当月块(同上) | 28 |
| 城市分市州 4 块 × 17 市州 × 6 值列 | 408 |
| 中口径分析 2 块 × 5 行 × 2 列 | 10 |
| 道路运输周转量 2 块 × 17 市州 × 6 列(G/L/Q + J/O/T + W/X/Y) | 102 |
| 合计 | 586 |
结果:**比对 586 格,差异 0 格**(_v5_four.txt 末尾「汇总:比对格数 = 586,差异格数 = 0」)。
补充自洽校验(全省行 = Σ17 市州):道路运输周转量 G4=17492129.04788293 = Σ(G5:G21)、L4=269628.07 = Σ(L5:L21)、Q4=1227147.48902 = Σ(Q5:Q21)、W4/X4/Y4 同理(差 ≤ 6e-11,浮点误差级)。
另:13:06 那一版归档件用 _verify_four.py 复核(含「与母版 1-7 月静态值对照」小节),同样**差异 0 格**。
与母版静态值的对照(证明「确实从静态变动态」):
| 单元格 | 母版(1-7 月静态) | 生成件(1-8 月) |
|---|---|---|
| 城市汇总 B3 | 237412.33 | 269628.07 |
| 城市汇总 A12 | 2026年7月全省完成城市客运量情况 | 2026年8月全省完成城市客运量情况 |
| 城市分市州 B6 | 135474.779894424 | 153695.70483259356 |
| 中口径分析 B3 | 27524.4906 | 31528.060700000005 |
| 道路运输周转量 G4 | 15222118.4463982 | 17492129.04788293 |
setCellValue 只写 <v>、不改 <is>,Excel 仍显示旧文案(7 月)。→ smSetTitle 改为先 setBlank() 再写。smSetVal 遇 FORMULA 直接跳过,写入格数 1056 小于四页理论格数即为此。fullCalcOnLoad)。ea7cc07(ReportExportService.java + 本报告 + 《工作日结_2026-09-13》共 3 文件,+689 −2)已推送双仓库:git push gitea main(09e612a..ea7cc07)、git push origin main:master(09e612a..ea7cc07),并 git branch -f master main。git fetch gitea / git fetch origin 均确认远端无新提交(git rev-list --left-right --count 均为 0 0),未覆盖同事代码。period=2026-08 → HTTP 200 / 950,783 字节 / 29.2 秒(第三次同尺寸);对发布后产物 _t4_2026-08.xlsx_v6_four.txt)。_t3_2026-08.xlsx 与发布后产物 _t4_2026-08.xlsx 逐 zip 条目比对,**全部内部条目xl/worksheets/*、xl/sharedStrings.xml 等)字节完全一致**;两者 MD5 不同仅源于 xlsx 容器的 zip 头时间戳,功能等价。git diff HEAD 为空)。