traffic-audit-server/src/main/java/com/trafficaudit/reportexport/service/ReportExportService.java
@@ -3232,7 +3232,8 @@
                log.info("汇总工作簿裁剪至 {} 月完成,清空/改写单元格数={}", toMonth, trimmed);
            }
            dynamicSummaryYear(wb, year);
            applyTwoDecimalFormat(wb); // 汇总大表保留人工母版列宽/版式:不做 autoFit(长公式会把列宽顶爆)
            cleanSummarySheetPresentation(wb); // 取消各页筛选、还原隐藏行(否则“班线包车”等页看起来像缺数据)
            applyTwoDecimalFormat(wb); // 数值显示两位小数(保留全精度);% / 日期等既有样式不改变
            if (!wb.getCTWorkbook().isSetCalcPr()) wb.getCTWorkbook().addNewCalcPr();
            wb.getCTWorkbook().getCalcPr().setFullCalcOnLoad(true); // 还原/改写公式后打开即重算
            return toBytes(wb);
@@ -4800,59 +4801,26 @@
    }
    /** 汇总表导出后按内容自动加宽列宽(只加宽不缩窄;跳过合并单元格标题,防长标题把单列撑爆) */
    private void autoFitContentColumns(org.apache.poi.ss.usermodel.Workbook wb) {
    /** 汇总大表输出前清理母版残留下来的筛选与行隐藏:筛选箭头/隐藏行会让整页看起来“缺数据” */
    private void cleanSummarySheetPresentation(org.apache.poi.ss.usermodel.Workbook wb) {
        if (wb == null) return;
        org.apache.poi.ss.usermodel.DataFormatter dfmt = new org.apache.poi.ss.usermodel.DataFormatter();
        for (int s = 0; s < wb.getNumberOfSheets(); s++) {
            org.apache.poi.ss.usermodel.Sheet sh = wb.getSheetAt(s);
            if (sh == null) continue;
            java.util.Set<String> merged = new java.util.HashSet<>();
            for (org.apache.poi.ss.util.CellRangeAddress ra : sh.getMergedRegions()) {
                for (int r = ra.getFirstRow(); r <= ra.getLastRow(); r++) {
                    for (int c = ra.getFirstColumn(); c <= ra.getLastColumn(); c++) {
                        merged.add(r + ":" + c);
                    }
            if (sh instanceof org.apache.poi.xssf.usermodel.XSSFSheet) {
                org.apache.poi.xssf.usermodel.XSSFSheet xs = (org.apache.poi.xssf.usermodel.XSSFSheet) sh;
                if (xs.getCTWorksheet().isSetAutoFilter()) xs.getCTWorksheet().unsetAutoFilter();
                for (org.apache.poi.ss.usermodel.Row row : xs) {
                    if (row == null) continue;
                    org.apache.poi.xssf.usermodel.XSSFRow xr = (org.apache.poi.xssf.usermodel.XSSFRow) row;
                    if (xr.getCTRow().isSetHidden()) xr.getCTRow().unsetHidden();
                }
            }
            int maxCol = -1;
            for (org.apache.poi.ss.usermodel.Row row : sh) {
                if (row == null) continue;
                maxCol = Math.max(maxCol, (int) row.getLastCellNum() - 1);
            }
            if (maxCol < 0) continue;
            int[] need = new int[maxCol + 1];
            for (org.apache.poi.ss.usermodel.Row row : sh) {
                if (row == null) continue;
                for (org.apache.poi.ss.usermodel.Cell cell : row) {
                    int c = cell.getColumnIndex();
                    if (c > maxCol || merged.contains(row.getRowNum() + ":" + c)) continue;
                    String txt;
                    try {
                        txt = dfmt.formatCellValue(cell);
                    } catch (Exception ignore) {
                        continue;
                    }
                    if (txt == null || txt.isEmpty()) continue;
                    int units = 0;
                    for (int i = 0; i < txt.length(); i++) {
                        units += isWideChar(txt.charAt(i)) ? 2 : 1;
                    }
                    if (units > need[c]) need[c] = Math.min(units, 34); // 长文本不把单列撑爆
                }
            }
            for (int c = 0; c <= maxCol; c++) {
                if (need[c] <= 0) continue;
                int target = Math.min(need[c] + 2, 46) * 256;
                if (target > sh.getColumnWidth(c)) sh.setColumnWidth(c, target);
            } else {
                sh.setAutoFilter(null);
            }
        }
    }
    /** CJK / 全角字符按两倍宽度计(近似 Excel 显示列宽) */
    private boolean isWideChar(char ch) {
        return (ch >= 0x2E80 && ch <= 0x9FFF) || (ch >= 0xF900 && ch <= 0xFAFF)
            || (ch >= 0xFF00 && ch <= 0xFFEF);
    }
    private byte[] toBytes(XSSFWorkbook wb) throws Exception {
        applyTwoDecimalFormat(wb);