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字符的边距,避免内容溢出
|
}
|
}
|