From 77193102a2038fafb71e03ac31e680257c40af75 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 26 Jul 2025 20:08:04 +0800 Subject: [PATCH] =?UTF-8?q?feat=EF=BC=9A=E6=B7=BB=E5=8A=A0=E8=87=AA?= =?UTF-8?q?=E9=80=82=E5=BA=94=E5=88=97=E5=AE=BD=E5=A4=84=E7=90=86=E5=99=A8?= =?UTF-8?q?=E5=B9=B6=E6=9B=BF=E6=8D=A2=E9=BB=98=E8=AE=A4=E5=88=97=E5=AE=BD?= =?UTF-8?q?=E7=AD=96=E7=95=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ColumnWidthMatchStyleStrategy.java | 78 +++++++++++++++++++ .../core/handler/SelectSheetWriteHandler.java | 2 +- .../framework/excel/core/util/ExcelUtils.java | 14 ++-- .../yudao/framework/excel/package-info.java | 2 +- 4 files changed, 87 insertions(+), 9 deletions(-) create mode 100644 yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/handler/ColumnWidthMatchStyleStrategy.java diff --git a/yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/handler/ColumnWidthMatchStyleStrategy.java b/yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/handler/ColumnWidthMatchStyleStrategy.java new file mode 100644 index 0000000000..49a5b31572 --- /dev/null +++ b/yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/handler/ColumnWidthMatchStyleStrategy.java @@ -0,0 +1,78 @@ +package cn.iocoder.yudao.framework.excel.core.handler; + +import cn.hutool.core.collection.CollUtil; +import cn.idev.excel.enums.CellDataTypeEnum; +import cn.idev.excel.metadata.Head; +import cn.idev.excel.metadata.data.WriteCellData; +import cn.idev.excel.util.MapUtils; +import cn.idev.excel.write.metadata.holder.WriteSheetHolder; +import cn.idev.excel.write.style.column.AbstractColumnWidthStyleStrategy; +import cn.idev.excel.write.style.column.LongestMatchColumnWidthStyleStrategy; +import org.apache.poi.ss.usermodel.Cell; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Excel 自适应列宽处理器 + * + * 相比 {@link LongestMatchColumnWidthStyleStrategy} 来说,额外处理了 DATE 类型! + * + * @see 添加自适应列宽处理器,并替换默认列宽策略 + * @author hmb + */ +public class ColumnWidthMatchStyleStrategy extends AbstractColumnWidthStyleStrategy { + + private static final int MAX_COLUMN_WIDTH = 255; + + private final Map> cache = MapUtils.newHashMapWithExpectedSize(8); + + @Override + protected void setColumnWidth(WriteSheetHolder writeSheetHolder, List> cellDataList, Cell cell, + Head head, Integer relativeRowIndex, Boolean isHead) { + boolean needSetWidth = isHead || CollUtil.isNotEmpty(cellDataList); + if (!needSetWidth) { + return; + } + Map maxColumnWidthMap = cache.computeIfAbsent(writeSheetHolder.getSheetNo(), + key -> new HashMap<>(16)); + Integer columnWidth = dataLength(cellDataList, cell, isHead); + if (columnWidth < 0) { + return; + } + if (columnWidth > MAX_COLUMN_WIDTH) { + columnWidth = MAX_COLUMN_WIDTH; + } + Integer maxColumnWidth = maxColumnWidthMap.get(cell.getColumnIndex()); + if (maxColumnWidth == null || columnWidth > maxColumnWidth) { + maxColumnWidthMap.put(cell.getColumnIndex(), columnWidth); + writeSheetHolder.getSheet().setColumnWidth(cell.getColumnIndex(), columnWidth * 256); + } + } + + @SuppressWarnings("EnhancedSwitchMigration") + private Integer dataLength(List> cellDataList, Cell cell, Boolean isHead) { + if (isHead) { + return cell.getStringCellValue().getBytes().length; + } + WriteCellData cellData = cellDataList.get(0); + CellDataTypeEnum type = cellData.getType(); + if (type == null) { + return -1; + } + switch (type) { + case STRING: + return cellData.getStringValue().getBytes().length; + case BOOLEAN: + return cellData.getBooleanValue().toString().getBytes().length; + case NUMBER: + return cellData.getNumberValue().toString().getBytes().length; + case DATE: + return cellData.getDateValue().toString().getBytes().length; + default: + return -1; + } + } + +} \ No newline at end of file diff --git a/yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/handler/SelectSheetWriteHandler.java b/yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/handler/SelectSheetWriteHandler.java index cd6c87f68f..c55e1210a2 100644 --- a/yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/handler/SelectSheetWriteHandler.java +++ b/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 { /** * 判断字段是否是静态的、最终的、 transient 的 - * 原因:EasyExcel 默认是忽略 static final 或 transient 的字段,所以需要判断 + * 原因:FastExcel 默认是忽略 static final 或 transient 的字段,所以需要判断 * * @param field 字段 * @return 是否是静态的、最终的、transient 的 diff --git a/yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/util/ExcelUtils.java b/yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/util/ExcelUtils.java index bae20d6c53..f05d3e51e5 100644 --- a/yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/util/ExcelUtils.java +++ b/yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/util/ExcelUtils.java @@ -1,10 +1,10 @@ package cn.iocoder.yudao.framework.excel.core.util; -import cn.iocoder.yudao.framework.common.util.http.HttpUtils; -import cn.iocoder.yudao.framework.excel.core.handler.SelectSheetWriteHandler; -import cn.idev.excel.EasyExcel; +import cn.idev.excel.FastExcelFactory; import cn.idev.excel.converters.longconverter.LongStringConverter; -import cn.idev.excel.write.style.column.LongestMatchColumnWidthStyleStrategy; +import cn.iocoder.yudao.framework.common.util.http.HttpUtils; +import cn.iocoder.yudao.framework.excel.core.handler.ColumnWidthMatchStyleStrategy; +import cn.iocoder.yudao.framework.excel.core.handler.SelectSheetWriteHandler; import jakarta.servlet.http.HttpServletResponse; import org.springframework.web.multipart.MultipartFile; @@ -32,9 +32,9 @@ public class ExcelUtils { public static void write(HttpServletResponse response, String filename, String sheetName, Class head, List data) throws IOException { // 输出 Excel - EasyExcel.write(response.getOutputStream(), head) + FastExcelFactory.write(response.getOutputStream(), head) .autoCloseStream(false) // 不要自动关闭,交给 Servlet 自己处理 - .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()) // 基于 column 长度,自动适配。最大 255 宽度 + .registerWriteHandler(new ColumnWidthMatchStyleStrategy()) // 基于 column 长度,自动适配。最大 255 宽度 .registerWriteHandler(new SelectSheetWriteHandler(head)) // 基于固定 sheet 实现下拉框 .registerConverter(new LongStringConverter()) // 避免 Long 类型丢失精度 .sheet(sheetName).doWrite(data); @@ -44,7 +44,7 @@ public class ExcelUtils { } public static List read(MultipartFile file, Class head) throws IOException { - return EasyExcel.read(file.getInputStream(), head, null) + return FastExcelFactory.read(file.getInputStream(), head, null) .autoCloseStream(false) // 不要自动关闭,交给 Servlet 自己处理 .doReadAllSync(); } diff --git a/yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/package-info.java b/yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/package-info.java index 53bc5c01bf..72c3ac42e1 100644 --- a/yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/package-info.java +++ b/yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/package-info.java @@ -1,4 +1,4 @@ /** - * 基于 EasyExcel 实现 Excel 相关的操作 + * 基于 FastExcel 实现 Excel 相关的操作 */ package cn.iocoder.yudao.framework.excel;