Commit 77193102a2038fafb71e03ac31e680257c40af75

Authored by YunaiV
1 parent 1b412546

feat:添加自适应列宽处理器并替换默认列宽策略

yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/handler/ColumnWidthMatchStyleStrategy.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.excel.core.handler;
  2 +
  3 +import cn.hutool.core.collection.CollUtil;
  4 +import cn.idev.excel.enums.CellDataTypeEnum;
  5 +import cn.idev.excel.metadata.Head;
  6 +import cn.idev.excel.metadata.data.WriteCellData;
  7 +import cn.idev.excel.util.MapUtils;
  8 +import cn.idev.excel.write.metadata.holder.WriteSheetHolder;
  9 +import cn.idev.excel.write.style.column.AbstractColumnWidthStyleStrategy;
  10 +import cn.idev.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
  11 +import org.apache.poi.ss.usermodel.Cell;
  12 +
  13 +import java.util.HashMap;
  14 +import java.util.List;
  15 +import java.util.Map;
  16 +
  17 +/**
  18 + * Excel 自适应列宽处理器
  19 + *
  20 + * 相比 {@link LongestMatchColumnWidthStyleStrategy} 来说,额外处理了 DATE 类型!
  21 + *
  22 + * @see <a href="https://github.com/YunaiV/yudao-cloud/pull/196/">添加自适应列宽处理器,并替换默认列宽策略</a>
  23 + * @author hmb
  24 + */
  25 +public class ColumnWidthMatchStyleStrategy extends AbstractColumnWidthStyleStrategy {
  26 +
  27 + private static final int MAX_COLUMN_WIDTH = 255;
  28 +
  29 + private final Map<Integer, Map<Integer, Integer>> cache = MapUtils.newHashMapWithExpectedSize(8);
  30 +
  31 + @Override
  32 + protected void setColumnWidth(WriteSheetHolder writeSheetHolder, List<WriteCellData<?>> cellDataList, Cell cell,
  33 + Head head, Integer relativeRowIndex, Boolean isHead) {
  34 + boolean needSetWidth = isHead || CollUtil.isNotEmpty(cellDataList);
  35 + if (!needSetWidth) {
  36 + return;
  37 + }
  38 + Map<Integer, Integer> maxColumnWidthMap = cache.computeIfAbsent(writeSheetHolder.getSheetNo(),
  39 + key -> new HashMap<>(16));
  40 + Integer columnWidth = dataLength(cellDataList, cell, isHead);
  41 + if (columnWidth < 0) {
  42 + return;
  43 + }
  44 + if (columnWidth > MAX_COLUMN_WIDTH) {
  45 + columnWidth = MAX_COLUMN_WIDTH;
  46 + }
  47 + Integer maxColumnWidth = maxColumnWidthMap.get(cell.getColumnIndex());
  48 + if (maxColumnWidth == null || columnWidth > maxColumnWidth) {
  49 + maxColumnWidthMap.put(cell.getColumnIndex(), columnWidth);
  50 + writeSheetHolder.getSheet().setColumnWidth(cell.getColumnIndex(), columnWidth * 256);
  51 + }
  52 + }
  53 +
  54 + @SuppressWarnings("EnhancedSwitchMigration")
  55 + private Integer dataLength(List<WriteCellData<?>> cellDataList, Cell cell, Boolean isHead) {
  56 + if (isHead) {
  57 + return cell.getStringCellValue().getBytes().length;
  58 + }
  59 + WriteCellData<?> cellData = cellDataList.get(0);
  60 + CellDataTypeEnum type = cellData.getType();
  61 + if (type == null) {
  62 + return -1;
  63 + }
  64 + switch (type) {
  65 + case STRING:
  66 + return cellData.getStringValue().getBytes().length;
  67 + case BOOLEAN:
  68 + return cellData.getBooleanValue().toString().getBytes().length;
  69 + case NUMBER:
  70 + return cellData.getNumberValue().toString().getBytes().length;
  71 + case DATE:
  72 + return cellData.getDateValue().toString().getBytes().length;
  73 + default:
  74 + return -1;
  75 + }
  76 + }
  77 +
  78 +}
0 79 \ No newline at end of file
... ...
yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/handler/SelectSheetWriteHandler.java
... ... @@ -86,7 +86,7 @@ public class SelectSheetWriteHandler implements SheetWriteHandler {
86 86  
87 87 /**
88 88 * 判断字段是否是静态的、最终的、 transient 的
89   - * 原因:EasyExcel 默认是忽略 static final 或 transient 的字段,所以需要判断
  89 + * 原因:FastExcel 默认是忽略 static final 或 transient 的字段,所以需要判断
90 90 *
91 91 * @param field 字段
92 92 * @return 是否是静态的、最终的、transient 的
... ...
yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/util/ExcelUtils.java
1 1 package cn.iocoder.yudao.framework.excel.core.util;
2 2  
  3 +import cn.idev.excel.FastExcelFactory;
  4 +import cn.idev.excel.converters.longconverter.LongStringConverter;
3 5 import cn.iocoder.yudao.framework.common.util.http.HttpUtils;
  6 +import cn.iocoder.yudao.framework.excel.core.handler.ColumnWidthMatchStyleStrategy;
4 7 import cn.iocoder.yudao.framework.excel.core.handler.SelectSheetWriteHandler;
5   -import cn.idev.excel.EasyExcel;
6   -import cn.idev.excel.converters.longconverter.LongStringConverter;
7   -import cn.idev.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
8 8 import jakarta.servlet.http.HttpServletResponse;
9 9 import org.springframework.web.multipart.MultipartFile;
10 10  
... ... @@ -32,9 +32,9 @@ public class ExcelUtils {
32 32 public static <T> void write(HttpServletResponse response, String filename, String sheetName,
33 33 Class<T> head, List<T> data) throws IOException {
34 34 // 输出 Excel
35   - EasyExcel.write(response.getOutputStream(), head)
  35 + FastExcelFactory.write(response.getOutputStream(), head)
36 36 .autoCloseStream(false) // 不要自动关闭,交给 Servlet 自己处理
37   - .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()) // 基于 column 长度,自动适配。最大 255 宽度
  37 + .registerWriteHandler(new ColumnWidthMatchStyleStrategy()) // 基于 column 长度,自动适配。最大 255 宽度
38 38 .registerWriteHandler(new SelectSheetWriteHandler(head)) // 基于固定 sheet 实现下拉框
39 39 .registerConverter(new LongStringConverter()) // 避免 Long 类型丢失精度
40 40 .sheet(sheetName).doWrite(data);
... ... @@ -44,7 +44,7 @@ public class ExcelUtils {
44 44 }
45 45  
46 46 public static <T> List<T> read(MultipartFile file, Class<T> head) throws IOException {
47   - return EasyExcel.read(file.getInputStream(), head, null)
  47 + return FastExcelFactory.read(file.getInputStream(), head, null)
48 48 .autoCloseStream(false) // 不要自动关闭,交给 Servlet 自己处理
49 49 .doReadAllSync();
50 50 }
... ...
yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/package-info.java
1 1 /**
2   - * 基于 EasyExcel 实现 Excel 相关的操作
  2 + * 基于 FastExcel 实现 Excel 相关的操作
3 3 */
4 4 package cn.iocoder.yudao.framework.excel;
... ...