Commit 77193102a2038fafb71e03ac31e680257c40af75
1 parent
1b412546
feat:添加自适应列宽处理器并替换默认列宽策略
Showing
4 changed files
with
86 additions
and
8 deletions
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 | } | ... | ... |