fei
昨天 ca4b62abd2560b6dcffbf3ff43da1b04427b494b
ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelUtilManySheet.java
@@ -527,6 +527,8 @@
    public void fillExcelData(int index, Row row) {
//        int startNo = index * sheetSize;
//        int endNo = Math.min(startNo + sheetSize, list.size());
        int startRow = (index == 1) ? 5 : 1;
        for (int i = 0; i < list.size(); i++) {
            if(index==1)
                row = sheet.createRow(i + 5 );
@@ -536,6 +538,7 @@
         //   sheet.autoSizeRow(0);
            // 第二步:获取自动计算后的行高
        //    row.setHeight((short) -1); // 先设为自动,由addCell计算后覆盖
            // 得到导出对象.
            T vo = (T) list.get(i);
@@ -548,10 +551,180 @@
                this.addCell(excel, row, vo, field, column++);
            }
            // 批量调整行高(数据填充完成后)
            if (list.size() > 0) {
                int lastRow = startRow + list.size() - 1;
                batchAdjustRowHeights(sheet, startRow, lastRow);
            }
        }
    }
    /**
     * 批量处理行高(在数据填充完成后统一计算)
     */
    /**
     * 批量处理行高(在数据填充完成后统一计算)
     */
    private String getCellStringValue(Cell cell) {
        if (cell == null) return null;
        switch (cell.getCellType()) {
            case STRING:
                return cell.getStringCellValue();
            case NUMERIC:
                return String.valueOf(cell.getNumericCellValue());
            case BOOLEAN:
                return String.valueOf(cell.getBooleanCellValue());
            case FORMULA:
                try {
                    return cell.getStringCellValue();
                } catch (Exception e) {
                    return String.valueOf(cell.getNumericCellValue());
                }
            default:
                return null;
        }
    }
    private void batchAdjustRowHeights(Sheet sheet, int startRow, int endRow) {
        Workbook workbook = sheet.getWorkbook();
        for (int rowNum = startRow; rowNum <= endRow; rowNum++) {
            Row row = sheet.getRow(rowNum);
            if (row == null) continue;
            int maxLinesInRow = 1; // 记录该行所有单元格中的最大行数
            // 第一步:遍历该行的所有单元格,找到最大行数需求
            for (int colNum = 0; colNum < row.getLastCellNum(); colNum++) {
                Cell cell = row.getCell(colNum);
                if (cell == null) continue;
                // 获取单元格内容
                String content = getCellStringValue(cell);
                if (content == null || content.isEmpty()) continue;
                // 获取列宽
                int columnWidth = sheet.getColumnWidth(colNum) / 256;
                if (columnWidth <= 0) columnWidth = 10; // 默认列宽
                // 计算该单元格内容需要的行数
                int contentLines = calculateContentLines(content, columnWidth);
                // 更新最大行数
                maxLinesInRow = Math.max(maxLinesInRow, contentLines);
            }
            // 第二步:根据最大行数设置行高(关键修复)
            if (maxLinesInRow > 1) {
                // 基础行高:一行文本的高度
                int baseHeightPerLine = 400; // 20点 = 400单位(建议值)
                // 计算总高度 = 行数 × 每行高度
                int newHeight = maxLinesInRow * baseHeightPerLine + 600;
                // 限制最小和最大高度
                int minHeight = 300;   // 15点
                int maxHeight = 10000; // 500点
                newHeight = Math.max(minHeight, Math.min(newHeight, maxHeight));
                // 设置行高
                row.setHeight((short) newHeight);
                // 可选:记录调整信息用于调试
                log.debug("Row {} adjusted: maxLines={}, height={}",
                        rowNum, maxLinesInRow, newHeight);
            }
        }
    }
    /**
     * 计算文本的有效字符宽度
     */
    private double calculateEffectiveWidth(String text) {
        if (text == null || text.isEmpty()) {
            return 0;
        }
        double totalWidth = 0;
        for (char c : text.toCharArray()) {
            if (isChineseChar(c)) {
                // 中文字符:1.0宽度
                totalWidth += 2.0;
            } else if (Character.isDigit(c)) {
                // 数字:0.6宽度
                totalWidth += 0.6;
            } else if (Character.isUpperCase(c)) {
                // 大写字母:0.7宽度
                totalWidth += 0.7;
            } else if (Character.isLowerCase(c)) {
                // 小写字母:0.5宽度
                totalWidth += 0.5;
            } else if (c == '.' || c == ',') {
                // 点号、逗号:0.3宽度
                totalWidth += 0.3;
            } else if (c == '-' || c == '_') {
                // 连字符、下划线:0.35宽度
                totalWidth += 0.35;
            } else if (c == ' ') {
                // 空格:0.3宽度
                totalWidth += 0.3;
            } else if (c == '\t') {
                // 制表符:4.0宽度
                totalWidth += 4.0;
            } else {
                // 其他字符:默认0.6宽度
                totalWidth += 0.6;
            }
        }
        return totalWidth;
    }
    /**
     * 计算单元格内容所需行数(更精确的版本)
     */
    private int calculateContentLines(String content, int columnWidthChars) {
        if (content == null || content.isEmpty() || columnWidthChars <= 0) {
            return 1;
        }
        int totalLines = 0;
        String[] lines = content.split("\n");
        for (String line : lines) {
            if (line.trim().isEmpty()) {
                totalLines++; // 空行也算一行
                continue;
            }
            // 计算该行需要的字符宽度
            // 考虑中英文字符宽度差异
            double effectiveLength = 0;
            effectiveLength += calculateEffectiveWidth(line); // 中文字符占1个宽度
            // 计算需要的行数
            int linesForText = (int) Math.ceil(effectiveLength / columnWidthChars);
            totalLines += Math.max(1, linesForText);
        }
        return Math.max(totalLines, 1);
    }
    /**
     * 判断是否为中文字符
     */
    private boolean isChineseChar(char c) {
        Character.UnicodeBlock ub = Character.UnicodeBlock.of(c);
        return ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS
                || ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS
                || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A
                || ub == Character.UnicodeBlock.GENERAL_PUNCTUATION
                || ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION
                || ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS;
    }
    /**
     * 创建表格样式
     *
@@ -736,7 +909,7 @@
        Cell cell = null;
        try {
            // 设置行高为自动调整
          //  row.setHeight((short) -1);
            row.setHeight((short) -1);
            // 根据Excel中设置情况决定是否导出,有些情况需要保持为空,希望用户填写这一列.
            if (attr.isExport()) {
                // 创建cell
@@ -751,6 +924,7 @@
                } else if (align == HorizontalAlignment.RIGHT) {
                    styleKey = "data3";
                }
                System.out.println(styleKey);
                // 获取并修改样式
                CellStyle style = styles.get(styleKey);
                Workbook workbook = row.getSheet().getWorkbook();
@@ -775,8 +949,16 @@
                    setCellVo(value, attr, cell);
                }
                adjustRowHeightAfterSetValue(row, cell, value);
                System.out.println(row.getHeight());
//             //   adjustRowHeightAfterSetValue(row, cell, value);
//                int defaultRowHeight = row.getHeight() / 20; // 原始行高(转成点数)
//                if(value==null)
//                    value="";
//                System.out.println(sheet.getColumnWidth(column));
//                int contentLines = getContentLines(value.toString(), sheet.getColumnWidth(column), style); // 计算换行后的行数
//                int newHeight = defaultRowHeight * contentLines; // 按行数调整行高(可加少量冗余)
//                row.setHeightInPoints((short) (newHeight)); // 提高行高(+2 是冗余,避免内容被截断)
                addStatisticsData(column, Convert.toStr(value), attr);
            }
        } catch (Exception e) {
@@ -784,65 +966,7 @@
        }
        return cell;
    }
    /**
     * 设置值后调整行高
     */
    private void adjustRowHeightAfterSetValue(Row row, Cell cell, Object value) {
        if (value == null) return;
        String text = value.toString();
        Sheet sheet = row.getSheet();
        // 1. 计算自动高度(基于内容)
        short autoHeight = calculateSimpleAutoHeight(text, cell);
        // 2. 获取当前行高
        short currentHeight = row.getHeight();
        if (currentHeight == -1) {
            currentHeight = sheet.getDefaultRowHeight();
        }
        // 3. 使用较大的高度(自动计算的高度或当前高度)
        short baseHeight = (short) Math.max(currentHeight, autoHeight);
        System.out.println(baseHeight+"aaaaaaaaatttttttt");
        // 4. 在基础上增加额外高度(100单位 = 5点)
        short extraHeight = 80;
        short newHeight = (short) (baseHeight + extraHeight);
        // 5. 限制最大高度
        short maxHeight = (short) 4000; // 100点
        row.setHeight((short) Math.min(maxHeight,newHeight));
    }
    /**
     * 简化的自动高度计算
     */
    private short calculateSimpleAutoHeight(String text, Cell cell) {
        if (text == null || text.isEmpty()) return 0;
        Sheet sheet = cell.getSheet();
        int colIndex = cell.getColumnIndex();
        // 获取列宽(字符数)
        int colWidthChars = sheet.getColumnWidth(colIndex) / 256;
        if (colWidthChars <= 0) colWidthChars = 10;
        // 计算文本行数
        int lines = 1;
        if (text.contains("\n")) {
            // 有显式换行
            String[] parts = text.split("\n");
            for (String part : parts) {
                lines += Math.max(1, (int) Math.ceil(part.length() * 1.5 / colWidthChars));
            }
        } else {
            // 自动换行
            lines = (int) Math.ceil(text.length() * 1.5 / colWidthChars);
        }
        // 每行高度:假设18点(360 POI单位)
        return (short) (lines * 360);
    }
    /**
     * 设置 POI HSSFSheet 单元格提示
     *