traffic-audit-server/src/main/java/com/trafficaudit/reportexport/layout/SummaryLayoutExpander.java
@@ -41,6 +41,19 @@
    private static final int HEADER_SCAN_ROWS = 15;
    /** 标题由程序在出表时现写的 7 个页签(母版里的标题文字需按母版期次重写)。 */
    private static final List<String> TITLE_PAGES = Arrays.asList(
            "货运量排名", "货运周转量排名", "城市汇总", "城市分市州", "中口径排名", "中口径分析", "道路运输周转量");
    /** 标题识别标记(命中其一才改写,避免误伤备注等文字)。 */
    private static final List<String> TITLE_MARKERS = Arrays.asList(
            "全省分市州累计完成公路货运量情况", "全省分市州完成公路货运量情况",
            "全省分市州累计完成公路货物运输周转量情况", "全省分市州完成公路货物运输周转量情况",
            "全省累计完成城市客运量情况", "全省完成城市客运量情况",
            "分市州1-", "全省分市州累计完成道路客运生产情况", "全省分市州完成道路客运生产情况",
            "中口径客运量及周转量",
            "全省累计完成交通周转量情况", "全省完成交通周转量情况");
    /** 公式里的 A1 引用(可带工作表前缀)。 */
    private static final Pattern REF = Pattern.compile(
            "(?:('([^']+)'|([A-Za-z_\\u4e00-\\u9fff][A-Za-z0-9_.\\u4e00-\\u9fff\u3001]*))!)?(\\$?)([A-Z]{1,3})(\\$?)(\\d+)");
@@ -67,6 +80,10 @@
                if (sh == null || expanded.contains(sh.getSheetName())) continue;
                shiftQualifiedRefs(sh, insertColOf);
            }
            int titleFixed = applyTitles(wb, year, targetMonth);
            if (titleFixed > 0) {
                log.info("扩列:标题按 {}年{}月 重写 {} 格", year, targetMonth, titleFixed);
            }
            wb.setForceFormulaRecalculation(true);
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            wb.write(out);
@@ -76,6 +93,54 @@
        }
    }
    /** 只把 7 个标题页的标题按给定期次重写(用于修正母版里滞后的标题)。 */
    public byte[] fixTitles(byte[] source, int year, int month) {
        try (XSSFWorkbook wb = new XSSFWorkbook(new ByteArrayInputStream(source))) {
            int n = applyTitles(wb, year, month);
            wb.setForceFormulaRecalculation(true);
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            wb.write(out);
            log.info("汇总大表标题修正完成:{}年{}月,改写 {} 格", year, month, n);
            return out.toByteArray();
        } catch (Exception e) {
            throw new IllegalStateException("汇总大表标题修正失败: " + e.getMessage(), e);
        }
    }
    /** 把 7 个页签的标题文字按「累计=1-M月、当月=M月」重写;命中标记才改,避免误伤备注。 */
    private int applyTitles(XSSFWorkbook wb, int year, int month) {
        int changed = 0;
        for (String page : TITLE_PAGES) {
            Sheet sh = wb.getSheet(page);
            if (sh == null) continue;
            int lastRow = Math.min(sh.getLastRowNum(), 40);
            for (int r = 0; r <= lastRow; r++) {
                Row row = sh.getRow(r);
                if (row == null) continue;
                for (int c = 0; c <= 1; c++) {
                    Cell cell = row.getCell(c);
                    if (cell == null || cell.getCellType() != CellType.STRING) continue;
                    String t = cell.getStringCellValue();
                    if (t == null || !looksLikeTitle(t)) continue;
                    String nt = t.replaceAll("(\\d{4})年", year + "年")
                                 .replaceAll("(\\d{1,2})月", month + "月");
                    if (!nt.equals(t)) {
                        cell.setCellValue(nt);
                        changed++;
                    }
                }
            }
        }
        return changed;
    }
    private boolean looksLikeTitle(String t) {
        for (String m : TITLE_MARKERS) {
            if (t.contains(m)) return true;
        }
        return false;
    }
    /** 对单页扩列,返回插入位置(0 基列号)。 */
    private int expandSheet(Sheet sh, int year, int targetMonth) {
        int lastMonth = targetMonth - 1;