From 54b3b5862690c6c2fcde104e8636c758824a93d3 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Fri, 9 Oct 2026 13:01:23 +0800 Subject: [PATCH] fix(excel): 修复中文表头列宽不足导致换行 --- yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/handler/ColumnWidthMatchStyleStrategy.java | 14 ++++++++------ yudao-framework/yudao-spring-boot-starter-excel/src/test/java/cn/iocoder/yudao/framework/excel/core/handler/ColumnWidthMatchStyleStrategyTest.java | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+), 6 deletions(-) create mode 100644 yudao-framework/yudao-spring-boot-starter-excel/src/test/java/cn/iocoder/yudao/framework/excel/core/handler/ColumnWidthMatchStyleStrategyTest.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 index 49a5b31..33344da 100644 --- 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 @@ -10,6 +10,7 @@ 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.nio.charset.StandardCharsets; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -41,6 +42,7 @@ public class ColumnWidthMatchStyleStrategy extends AbstractColumnWidthStyleStrat if (columnWidth < 0) { return; } + columnWidth += 2; // 留出单元格边距,避免短表头换行 if (columnWidth > MAX_COLUMN_WIDTH) { columnWidth = MAX_COLUMN_WIDTH; } @@ -54,7 +56,7 @@ public class ColumnWidthMatchStyleStrategy extends AbstractColumnWidthStyleStrat @SuppressWarnings("EnhancedSwitchMigration") private Integer dataLength(List> cellDataList, Cell cell, Boolean isHead) { if (isHead) { - return cell.getStringCellValue().getBytes().length; + return cell.getStringCellValue().getBytes(StandardCharsets.UTF_8).length; } WriteCellData cellData = cellDataList.get(0); CellDataTypeEnum type = cellData.getType(); @@ -63,16 +65,16 @@ public class ColumnWidthMatchStyleStrategy extends AbstractColumnWidthStyleStrat } switch (type) { case STRING: - return cellData.getStringValue().getBytes().length; + return cellData.getStringValue().getBytes(StandardCharsets.UTF_8).length; case BOOLEAN: - return cellData.getBooleanValue().toString().getBytes().length; + return cellData.getBooleanValue().toString().getBytes(StandardCharsets.UTF_8).length; case NUMBER: - return cellData.getNumberValue().toString().getBytes().length; + return cellData.getNumberValue().toString().getBytes(StandardCharsets.UTF_8).length; case DATE: - return cellData.getDateValue().toString().getBytes().length; + return cellData.getDateValue().toString().getBytes(StandardCharsets.UTF_8).length; default: return -1; } } -} \ No newline at end of file +} diff --git a/yudao-framework/yudao-spring-boot-starter-excel/src/test/java/cn/iocoder/yudao/framework/excel/core/handler/ColumnWidthMatchStyleStrategyTest.java b/yudao-framework/yudao-spring-boot-starter-excel/src/test/java/cn/iocoder/yudao/framework/excel/core/handler/ColumnWidthMatchStyleStrategyTest.java new file mode 100644 index 0000000..c45383c --- /dev/null +++ b/yudao-framework/yudao-spring-boot-starter-excel/src/test/java/cn/iocoder/yudao/framework/excel/core/handler/ColumnWidthMatchStyleStrategyTest.java @@ -0,0 +1,82 @@ +package cn.iocoder.yudao.framework.excel.core.handler; + +import cn.idev.excel.FastExcelFactory; +import cn.idev.excel.annotation.ExcelProperty; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import org.junit.jupiter.api.Test; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.util.Collections; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * {@link ColumnWidthMatchStyleStrategy} 的单元测试 + * + * @author 芋道源码 + */ +public class ColumnWidthMatchStyleStrategyTest { + + @Test + public void testWrite_emptyChineseHeader() throws Exception { + // 调用 + try (XSSFWorkbook workbook = write(Collections.emptyList())) { + // 断言:空列表导出的中文短表头也保留足够宽度 + assertEquals("标题", workbook.getSheetAt(0).getRow(0).getCell(0).getStringCellValue()); + assertTrue(workbook.getSheetAt(0).getColumnWidth(0) >= 8 * 256); + } + } + + @Test + public void testWrite_longestValue() throws Exception { + // mock 数据 + TestRow row = new TestRow(); + row.setName("自动化测试工作项标题"); + + // 调用 + try (XSSFWorkbook workbook = write(Collections.singletonList(row))) { + // 断言:数据内容比表头长时继续扩展列宽 + assertTrue(workbook.getSheetAt(0).getColumnWidth(0) > 8 * 256); + assertEquals(row.getName(), workbook.getSheetAt(0).getRow(1).getCell(0).getStringCellValue()); + } + } + + @Test + public void testWrite_maxColumnWidth() throws Exception { + // mock 数据 + TestRow row = new TestRow(); + row.setName("测试".repeat(100)); + + // 调用 + try (XSSFWorkbook workbook = write(Collections.singletonList(row))) { + // 断言:留白后仍不超过 Excel 的列宽上限 + assertEquals(255 * 256, workbook.getSheetAt(0).getColumnWidth(0)); + } + } + + private XSSFWorkbook write(List rows) throws Exception { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + FastExcelFactory.write(outputStream, TestRow.class) + .registerWriteHandler(new ColumnWidthMatchStyleStrategy()).sheet().doWrite(rows); + return new XSSFWorkbook(new ByteArrayInputStream(outputStream.toByteArray())); + } + + public static class TestRow { + + @ExcelProperty("标题") + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + } + +} -- libgit2 0.21.4