feat: 汇总大表版式统一——数值0.00/排名整数/列宽自适应/去底色(7月8月母版+还原源+applyDonorNumberFormat)
4个文件已修改
1个文件已添加
74 ■■■■■ 已修改文件
docs/功能测试报告/功能测试报告_汇总大表版式统一_2026-09-08.md 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
docs/工作日结/工作日结_2026-09-08.md 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
docs/生成汇总大表/2026年7月道路运输量汇总表.xlsx 补丁 | 查看 | 原始文档 | blame | 历史
docs/生成汇总大表/2026年8月道路运输量汇总表.xlsx 补丁 | 查看 | 原始文档 | blame | 历史
traffic-audit-server/src/main/java/com/trafficaudit/reportexport/service/ReportExportService.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
docs/¹¦ÄܲâÊÔ±¨¸æ/¹¦ÄܲâÊÔ±¨¸æ_»ã×Ü´ó±í°æÊ½Í³Ò»_2026-09-08.md
New file
@@ -0,0 +1,42 @@
# åŠŸèƒ½æµ‹è¯•æŠ¥å‘Š_汇总大表版式统一_2026-09-08
## ä¸€ã€åŠŸèƒ½è¯´æ˜Ž
用户拍板(2026-09-08):汇总大表版式统一,四项规则——
1) æ•°å€¼ä¿ç•™ä¸¤ä½å°æ•°ï¼ˆæ•°å€¼/公式格显示 0.00,同比百分比 0.00% ä¿ç•™ï¼‰ï¼›
2) æŽ’名列整数(格式 0);
3) è¡¨æ ¼åˆ—宽按内容自适应(长公式文本不再把列撑爆);
4) èƒŒæ™¯è‰²å…¨éƒ¨ç»Ÿä¸€åŽ»é™¤ï¼ˆæ— å¡«å……ï¼‰ã€‚
涉及文件:
- æ¯ç‰ˆï¼š`docs/生成汇总大表/2026å¹´7月道路运输量汇总表.xlsx`、`2026å¹´8月道路运输量汇总表.xlsx`
- è¿˜åŽŸæºï¼ˆåŒåšå½’ä¸€ï¼Œé˜²ç”Ÿæˆæ—¶æ—§åº•è‰²/旧格式“复活”):`_备份_2026å¹´7月道路运输量汇总表_清理前_20260904.xlsx`
- ç¨‹åºï¼š`ReportExportService`(新增 `applyDonorNumberFormat`:还原回填时同步 donor æ•°å­—格式)
## äºŒã€æµ‹è¯•环境
- åŽç«¯ 8090(`start-dev.ps1` å¯åŠ¨ï¼‰ï¼Œ`mvn -q -DskipTests compile` exit=0
- æŽ¥å£ï¼š`GET /api/report/export/summaryWorkbook?period=2026-07|2026-08&mode=month`
- æ ¡éªŒï¼špython3 + openpyxl,值级/样式级双读(data_only=False)diff
## ä¸‰ã€ç”¨ä¾‹è¡¨
| # | ç”¨ä¾‹ | æ“ä½œ | é¢„期 | å®žé™… | ç»“论 |
|---|---|---|---|---|---|
| 1 | æ¯ç‰ˆåŽ»åº•è‰² | 7/8 æœˆæ¯ç‰ˆä¸Žå¤‡ä»½ç»Ÿä¸€è„šæœ¬å¤„ç† | å…¨ç°¿æ—  solid å¡«å…… | 7 æœˆæ¯ç‰ˆ fills=0;8 æœˆæ¯ç‰ˆæ¸…除 57908 æ ¼åº•色后=0;备份清除 57886 æ ¼åŽ=0 | é€šè¿‡ |
| 2 | æ•°å€¼ä¸¤ä½å°æ•° | æ•°å€¼+公式格按列语义归一 | æ•°æ®æ ¼æ˜¾ç¤º 0.00,同比/百分比保留 | 7 æœˆæ¯ç‰ˆ 38778 æ ¼å½’一;导出 7/8 æœˆæ•°æ®æ ¼å‡ 0.00 / 0.00% | é€šè¿‡ |
| 3 | æŽ’名整数 | æŽ’名列表头列数据格设为 0 | æŽ’名显示整数 | æ¯ç‰ˆä¸Žå¯¼å‡ºæŽ’名列均为 0;抽查`货运量排名`/`中口径排名`正确 | é€šè¿‡ |
| 4 | åˆ—宽自适应 | å…¬å¼ä¸è®¡å®½ã€æ•°å€¼åˆ—保底 12 | é•¿å…¬å¼åˆ—收缩到数值宽 | `货运` I/V/X…由 42 â†’ 12;长文本列(如 Q)保留 | é€šè¿‡ |
| 5 | å†…容不变 | å¤„理前后全簿值级 diff | diff=0 | 7 æœˆ v1→v2 diff=0;8 æœˆæš‚å­˜ vs åŽŸæ¯ç‰ˆä»… 6 å¤„空串`''→None` | é€šè¿‡ |
| 6 | 7 æœˆå¯¼å‡ºç«¯åˆ°ç«¯ | æ–°ç‰ˆå¼æ¯ç‰ˆ+备份生成 2026-07 | æ— åº•色、格式统一、校验行底色不复活 | fills=0;出租/公交月值 0.00、同比 0.00%、`货运`r117/118 æ ¡éªŒè¡Œ 0.00 ä¸”无底色;残余仅原表遗留日期锚点列 | é€šè¿‡ |
| 7 | 8 æœˆå¯¼å‡ºç«¯åˆ°ç«¯ | ç”Ÿæˆ 2026-08 | ä¸Ž 8 æœˆæ¯ç‰ˆ 0 å·®å¼‚、无底色 | å€¼ diff=0;fills=0;抽查格式正确 | é€šè¿‡ |
| 8 | Java ç¼–译 | `mvn -q -DskipTests compile` | exit=0 | exit=0 | é€šè¿‡ |
## å››ã€å‘现的问题与处置
1. **骨架空列还原时格式丢失/底色复活**:母版 5-7 æœˆåˆ—已清空(含同比公式),导出还原只写值不写样式,导致整数值显示 `1234`(缺 .00)、同比公式以 General æ˜¾ç¤ºå°æ•°æ¯”例、`货运`r117/118 æ ¡éªŒè¡ŒæŠŠå¤‡ä»½æ—§åº•色带回(30 æ ¼ï¼‰ã€‚
   å¤„置:(a) å¤‡ä»½æºæ–‡ä»¶åŒåšç‰ˆå¼ç»Ÿä¸€ï¼ˆåŽ»åº•è‰²ã€0.00、排名 0);(b) Java æ–°å¢ž `applyDonorNumberFormat`,还原回填时同步 donor æ•°å­—格式,同比/整数值/校验行显示统一。
2. **列宽被长公式撑爆**:首版自适应把公式文本计入宽度,I/V/X…列被撑到 42。处置:宽度仅按静态内容计算、长公式不计宽、数值/公式列保底 12。
3. **列语义误判**:行 3 æœŸæ¬¡æ—¥æœŸåºåˆ—(46082…)曾使整列被判“日期列”漏归一。处置:日期格数 â‰¤ æ•°å€¼æ ¼æ•°æ—¶æŒ‰æ•°å€¼åˆ—归一(日期序列所在单元格格式不动)。
4. **Excel å ç”¨ 8 æœˆæ¯ç‰ˆ**:openpyxl æ— æ³•落盘;等待用户关闭窗口后覆盖,预览副本先行提供桌面。
5. **日期锚点列(原表遗留)**:2019-2026 åºåˆ—号 General æœŸæ¬¡è¡Œï¼ˆå¦‚`公路总客运`r2 60 æ ¼ã€`中口径计算过程`A åˆ— 192 æ ¼ï¼‰éžæ•°æ®ï¼Œæœªæ”¹åŠ¨ï¼›å¦‚éœ€ç»Ÿä¸€ä¸ºæ—¥æœŸæ˜¾ç¤ºå¯å¦è¡Œæ‹æ¿ã€‚
## äº”、结论
- ç‰ˆå¼ç»Ÿä¸€å››é¡¹è§„则在 7/8 æœˆæ¯ç‰ˆä¸Žå¯¼å‡ºäº§ç‰©ç«¯åˆ°ç«¯ç”Ÿæ•ˆï¼›å…¨ç°¿å†…容零改动。
- åŽç»­ï¼š8 æœˆå½“月数据导入后按 M2/M3 å¡«å€¼å¹¶å¤éªŒï¼›æ—¥æœŸé”šç‚¹åˆ—显示方式待业务确认。
docs/¹¤×÷ÈÕ½á/¹¤×÷ÈÕ½á_2026-09-08.md
@@ -46,3 +46,16 @@
### é—留与下一步
- M2 SummaryFiller、M3 8 æœˆå®žå¼¹ï¼ˆ8 æœˆæ•°æ®å¯¼å…¥åŽå¡«å½“月值与排名)、小表前端隐藏(M4)。
- 8 æœˆæ–°æ¯ç‰ˆçš„ 8 æœˆå½“月值列仍为空,等待数据导入与填值验证。
---
## è¡¥å……(2026-09-08 ä¸‹åˆï¼ŒåŒä¸€ä¼šè¯ç»­ï¼‰ï¼šæ±‡æ€»å¤§è¡¨ç‰ˆå¼ç»Ÿä¸€ï¼ˆæ•°å€¼0.00/排名整数/列宽自适应/去底色)
### ä»Šæ—¥æ–°å¢ž
1. **母版版式统一**:7 æœˆã€8 æœˆæ¯ç‰ˆåŠ 7 æœˆæ¸…理前备份(还原源)统一处理——去除全部 solid åº•色(8 æœˆ 57908 æ ¼ã€å¤‡ä»½ 57886 æ ¼ï¼‰ã€æ•°å€¼ä¸Žå…¬å¼æ ¼æŒ‰åˆ—归一 0.00、排名列 0、列宽按静态内容自适应(长公式不计宽、数值列保底 12,`货运`I/V/X ç”± 42 æ”¶ç¼©åˆ° 12)。
2. **程序同步**:`ReportExportService.applyDonorNumberFormat`——还原回填 5-7 æœˆå—时同步 donor æ•°å­—格式,修复整数值缺 .00、同比公式 General æ˜¾ç¤ºå°æ•°æ¯”例、校验行旧底色复活三类问题。
3. **验证产物**:导出 2026-07/2026-08 ç«¯åˆ°ç«¯å¤éªŒï¼ˆfills=0、抽查格式正确、8 æœˆä¸Žæ¯ç‰ˆå€¼ diff=0),详见《功能测试报告_汇总大表版式统一_2026-09-08.md》。
### æµ‹è¯•结果摘要
- 7/8 æœˆæ¯ç‰ˆä¸Žå¯¼å‡ºå…¨ç°¿æ— åº•色;数值格 0.00/0.00%;排名列 0;内容零改动。
- `mvn -q -DskipTests compile` exit=0。
### é—留与下一步
- 8 æœˆå½“月数据导入后按 M2/M3 å¡«å€¼å¤éªŒï¼›æ—¥æœŸé”šç‚¹åˆ—(原表 General åºåˆ—号期次行)显示方式待业务确认。
- ä¸´æ—¶è„šæœ¬ `_unify_all.py` åŠ `_test_tmp/` å‰¯æœ¬ä¸åˆ ä¸å…¥åº“。
docs/Éú³É»ã×Ü´ó±í/2026Äê7ÔµÀ·ÔËÊäÁ¿»ã×ܱí.xlsx
Binary files differ
docs/Éú³É»ã×Ü´ó±í/2026Äê8ÔµÀ·ÔËÊäÁ¿»ã×ܱí.xlsx
Binary files differ
traffic-audit-server/src/main/java/com/trafficaudit/reportexport/service/ReportExportService.java
@@ -3551,6 +3551,7 @@
                    Cell tc = (bc != null) ? bc : tr.getCell(dc.getColumnIndex());
                    if (tc == null) tc = tr.createCell(dc.getColumnIndex());
                    tc.setBlank();
                    applyDonorNumberFormat(wb, tc, dc);
                    if (t == CellType.FORMULA) {
                        String f = dc.getCellFormula();
                        if (f != null) tc.setCellFormula(f);
@@ -3568,6 +3569,24 @@
        return restored;
    }
    /** è¿˜åŽŸå›žå¡«æ—¶åŒæ­¥ donor(已做版式统一)的数字格式,保证同比/数值/排名格显示格式与母版一致 */
    private void applyDonorNumberFormat(XSSFWorkbook wb, Cell dst, Cell src) {
        if (wb == null || dst == null || src == null) return;
        try {
            String fmt = src.getCellStyle().getDataFormatString();
            if (fmt == null || fmt.isEmpty() || "General".equalsIgnoreCase(fmt)) return;
            org.apache.poi.ss.usermodel.DataFormat df = wb.createDataFormat();
            short idx = df.getFormat(fmt);
            CellStyle cur = dst.getCellStyle();
            if (cur != null && idx == cur.getDataFormat()) return;
            CellStyle ns = wb.createCellStyle();
            if (cur != null) ns.cloneStyleFrom(cur);
            ns.setDataFormat(idx);
            dst.setCellStyle(ns);
        } catch (Exception ignore) {
            // ä¸ªåˆ«æ ¼å¼å¼‚常不阻塞还原
        }
    }
    /** å•元格内容文本化(公式带 = å‰ç¼€ï¼‰ï¼Œç”¨äºŽè·¨ç°¿æ¯”对 */
    private String summaryCellText(Cell c) {
        if (c == null) return null;