zouyu
2 天以前 2ea3b36a810adcb639f4d3c72c860f722f601927
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
package com.ruoyi.common.utils.excel;
 
import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.metadata.data.CellData;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.write.handler.CellWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Sheet;
 
import java.util.HashMap;
import java.util.List;
import java.util.Map;
 
/**
 * 完全自定义自适应列宽处理器
 */
public class FullCustomAutoWidthHandler implements CellWriteHandler {
    // 存储每列最大宽度(字符)
    private final Map<Integer, Integer> columnMaxWidth = new HashMap<>();
    // 配置每列的特殊规则(如第0列最大宽度20)
    private final Map<Integer, Integer> columnMaxWidthRules;
    private final int defaultMaxWidth;
    private final int defaultMinWidth;
 
    public FullCustomAutoWidthHandler() {
        this(new HashMap<>(), 30, 8);
    }
 
    public FullCustomAutoWidthHandler(Map<Integer, Integer> columnMaxWidthRules, 
                                     int defaultMaxWidth, int defaultMinWidth) {
        this.columnMaxWidthRules = columnMaxWidthRules;
        this.defaultMaxWidth = defaultMaxWidth;
        this.defaultMinWidth = defaultMinWidth;
    }
 
    @Override
    public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, List<WriteCellData<?>> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {
        int columnIndex = cell.getColumnIndex();
        String cellValue = cell.getStringCellValue();
        int contentWidth = calculateStringWidth(cellValue);
 
        // 更新最大宽度
        columnMaxWidth.put(columnIndex,
                Math.max(columnMaxWidth.getOrDefault(columnIndex, 0), contentWidth));
 
        // 所有数据写入完成后设置列宽(最后一行处理时)
        Sheet sheet = writeSheetHolder.getSheet();
        if (cell.getRowIndex() == sheet.getLastRowNum()) {
            int finalWidth = columnMaxWidth.get(columnIndex);
            // 应用特殊规则或默认规则
            int maxWidth = columnMaxWidthRules.getOrDefault(columnIndex, defaultMaxWidth);
            finalWidth = Math.min(finalWidth, maxWidth);
            finalWidth = Math.max(finalWidth, defaultMinWidth);
 
            sheet.setColumnWidth(columnIndex, finalWidth * 256);
        }
    }
 
    /**
     * 计算字符串显示宽度(中文算2字符,英文/数字算1字符)
     */
    private int calculateStringWidth(String value) {
        if (value == null || value.isEmpty()) return 0;
        int width = 0;
        for (char c : value.toCharArray()) {
            width += (c > 255) ? 2 : 1; // 中文占2字符,英文占1字符
        }
        return width + 2; // 额外加2字符的边距,避免内容溢出
    }
}