traffic-audit-server/src/main/java/com/trafficaudit/reportexport/service/ReportExportService.java
@@ -1439,10 +1439,11 @@
        Map<String, ScaleSplitTransport> result = new HashMap<>();
        List<ScaleSplitTransport> list = scaleSplitMapper.selectList(
            new LambdaQueryWrapper<ScaleSplitTransport>()
                .eq(ScaleSplitTransport::getPeriodType, "CUMULATIVE"));
                .eq(ScaleSplitTransport::getPeriodType, "CUMULATIVE")
                .eq(ScaleSplitTransport::getReportPeriod, period));   // 2026-10-12:只认目标期,缺数留空、不静默回退上一期
        for (ScaleSplitTransport record : list) {
            if (record.getReportPeriod() == null) continue;
            if (record.getReportPeriod().compareTo(period) > 0) continue;
            if (!period.equals(record.getReportPeriod())) continue;
            String city = RegionUtil.normalizeCityName(record.getRegionName());
            if (city == null) continue;
            if ("湖北省".equals(city)) continue;
@@ -1475,11 +1476,12 @@
    private ScaleSplitTransport getProvinceCumulative(String period) {
        List<ScaleSplitTransport> list = scaleSplitMapper.selectList(
            new LambdaQueryWrapper<ScaleSplitTransport>()
                .eq(ScaleSplitTransport::getPeriodType, "CUMULATIVE"));
                .eq(ScaleSplitTransport::getPeriodType, "CUMULATIVE")
                .eq(ScaleSplitTransport::getReportPeriod, period));   // 2026-10-12:同上(只认目标期)
        ScaleSplitTransport best = null;
        for (ScaleSplitTransport record : list) {
            if (record.getReportPeriod() == null) continue;
            if (record.getReportPeriod().compareTo(period) > 0) continue;
            if (!period.equals(record.getReportPeriod())) continue;
            String name = RegionUtil.normalizeCityName(record.getRegionName());
            if (!"湖北省".equals(name)) continue;
            if (best == null || record.getReportPeriod().compareTo(best.getReportPeriod()) > 0) best = record;
@@ -3764,7 +3766,9 @@
            reportProgress(progress, 45, "刷新排名页与跨页合成页");
            int rankRefreshed = refreshSummaryRankSheets(wb, effPeriod, "month");
            int cumulativeRefreshed = refreshSummaryCumulativeSheets(wb, year, effMonth); // 四张跨页合成页随报表期刷新
            int widthApplied = applySummaryReferenceLayout(wb);
            // 2026-10-12:停用「套用外部参照件《生成_道路运输量汇总表.xlsx》列宽」——版式一律以当期母版为准,
            // 避免母版与参照件两处维护(母版已并入参照件的列宽/隐藏)。
            int widthApplied = 0;
            log.info("汇总工作簿数据驱动回填完成:写入当月值格数={},补写当月同比公式格数={},补写当月合计公式格数={},"
                    + "修正累计同比分母格数={},刷新排名页数值格数={},刷新四页(城市汇总/城市分市州/中口径分析/道路运输周转量)数值格数={},"
                    + "按《生成_道路运输量汇总表》对齐列宽列数={},缺数提示={}",
@@ -3986,15 +3990,38 @@
                int colOff = dstTitle.getColumnIndex() - sc0;
                int h = rankBlockHeight(src, sr0, sc0);
                int w = rankBlockWidth(src, sr0, sc0);
                // 2026-10-12:整块缺数(源侧一个数值都没有,如 9 月缺②③时的周转量排名)→ 目标块只留标题与标签,
                // 数据/排名/占比一律留空;否则母版的 RANK/占比公式会在空块上算出「全 1 + #DIV/0!」。
                boolean blockHasData = false;
                for (int r = 1; r < h && !blockHasData; r++) {
                    Row sr = src.getRow(sr0 + r);
                    if (sr == null) continue;
                    for (int c = 0; c < w; c++) {
                        Cell sc0c = sr.getCell(sc0 + c);
                        if (sc0c != null && rankNumeric(sc0c, ev) != null) {
                            blockHasData = true;
                            break;
                        }
                    }
                }
                for (int r = 0; r < h; r++) {
                    Row srcRow = src.getRow(sr0 + r);
                    if (srcRow == null) continue;
                    Row dstRow = dst.getRow(sr0 + r + rowOff);
                    if (dstRow == null) dstRow = dst.createRow(sr0 + r + rowOff);
                    for (int c = 0; c < w; c++) {
                        Cell sc = srcRow.getCell(sc0 + c);
                        if (sc == null) continue;
                        int dc = sc0 + c + colOff;
                        Cell sc = srcRow.getCell(sc0 + c);
                        if (!blockHasData && r > 0) {
                            // 整块缺数:只保留标签(市州名/指标名),数据与排名/占比重算结果一律留空
                            if (sc == null || !isRankLabel(sc)) clearRankCell(dstRow, dc);
                            continue;
                        }
                        if (sc == null) {
                            // 2026-10-12:源侧整格缺失 = 缺数 → 目标格按「缺数留空」清空(不再沿用母版上一报表期的旧值)
                            if (r > 0) clearRankCell(dstRow, dc);
                            continue;
                        }
                        if (r == 0) {
                            // 标题行:同步块标题文案。母版标题是 inlineStr,POI 的 setCellValue 只写 <v>、
                            // 不更新 <is>,Excel 会继续显示旧月份,必须先 setBlank 清掉再写。
@@ -4029,7 +4056,12 @@
                            continue;
                        }
                        Double v = rankNumeric(sc, ev);
                        if (v == null) continue;
                        if (v == null) {
                            // 2026-10-12:源侧数值位为空(如缺②全口径时排名表的「规下」列)= 缺数 → 留空;
                            // 源侧是标签文本(市州名/指标名)时不是缺数,保留母版自带内容。
                            if (!isRankLabel(sc)) clearRankCell(dstRow, dc);
                            continue;
                        }
                        if (dcCell == null) dcCell = rankCell(dstRow, dc);
                        dcCell.setCellValue(v);
                        copied++;
@@ -4048,6 +4080,34 @@
        return c;
    }
    /**
     * 目标格按「缺数留空」清空。
     *
     * <p>2026-10-12:这里连母版自带的排名/占比公式格一起清(缺数期不显示"上一期残留值 + 全 1 排名 + #DIV/0!"),
     * 与《生成_货运量排名/周转量排名/中口径排名》这些用户日常核对件的空态一致;下期源侧有数时按源侧重写回来。
     * 文字标签格不动。
     */
    private void clearRankCell(Row dstRow, int col) {
        Cell c = dstRow.getCell(col);
        if (c == null) return;
        if (c.getCellType() != CellType.STRING) c.setBlank();
    }
    /** 源侧是否为文字标签(市州名/指标名)——标签不是缺数,不清空目标格 */
    private boolean isRankLabel(Cell c) {
        if (c.getCellType() != CellType.STRING) return false;
        String v = c.getStringCellValue();
        if (v == null) return false;
        String x = v.replace(",", "").trim();
        if (x.isEmpty()) return false;
        try {
            Double.parseDouble(x);
            return false;
        } catch (NumberFormatException ignore) {
            return true;
        }
    }
    /** 公式内所有 A1 引用整体平移:列 +dCol、行 +dRow(SUM/RANK 等函数名后接括号不会被匹配) */
    private String shiftFormula(String formula, int dCol, int dRow) {
        if (formula == null || (dCol == 0 && dRow == 0)) return formula;