| | |
| | | if (columnWidth < 0) { |
| | | return; |
| | | } |
| | | // 字段上声明了 @ColumnWidth 时,以声明值为下限。 |
| | | // 否则注解值会被本策略覆盖:EasyExcel 自己的 AbstractHeadColumnWidthStyleStrategy(负责把 |
| | | // @ColumnWidth 写进列宽)与本策略 order 相同(都是 0,按注册顺序排在前面), |
| | | // 本策略按内容长度后写,直接把声明的宽度冲掉 —— 例如「2026-10-13 10:10:20」只有 19 个字符, |
| | | // 列宽就停在 19,声明再大也没用。取最大值后,注解成了内容长度的下限,只放宽不收窄。 |
| | | if (isHead && head != null && head.getColumnWidthProperty() != null) { |
| | | columnWidth = Math.max(columnWidth, head.getColumnWidthProperty().getWidth()); |
| | | } |
| | | if (columnWidth > MAX_COLUMN_WIDTH) { |
| | | columnWidth = MAX_COLUMN_WIDTH; |
| | | } |
| | |
| | | } |
| | | } |
| | | |
| | | /** 按 Excel 列宽估计表头:中日韩宽字符占两格,并为边距留出空间。 */ |
| | | private int headerWidth(String text) { |
| | | int widest = 0; |
| | | int line = 0; |
| | | for (int offset = 0; offset < text.length();) { |
| | | int cp = text.codePointAt(offset); |
| | | offset += Character.charCount(cp); |
| | | if (cp == '\n' || cp == '\r') { |
| | | widest = Math.max(widest, line); |
| | | line = 0; |
| | | continue; |
| | | } |
| | | Character.UnicodeScript script = Character.UnicodeScript.of(cp); |
| | | boolean wide = script == Character.UnicodeScript.HAN || script == Character.UnicodeScript.HIRAGANA |
| | | || script == Character.UnicodeScript.KATAKANA || script == Character.UnicodeScript.HANGUL |
| | | || (cp >= 0xff01 && cp <= 0xff60) || (cp >= 0xffe0 && cp <= 0xffe6); |
| | | line += wide ? 2 : 1; |
| | | } |
| | | return Math.max(widest, line); |
| | | } |
| | | |
| | | @SuppressWarnings("EnhancedSwitchMigration") |
| | | private Integer dataLength(List<WriteCellData<?>> cellDataList, Cell cell, Boolean isHead) { |
| | | if (isHead) { |
| | | return cell.getStringCellValue().getBytes().length; |
| | | return Math.max(12, headerWidth(cell.getStringCellValue()) + 3); |
| | | } |
| | | WriteCellData<?> cellData = cellDataList.get(0); |
| | | CellDataTypeEnum type = cellData.getType(); |