| | |
| | | private static final Pattern EXTEND_FIELD_SOURCE_PATTERN = Pattern.compile("^extendFields\\.\\[(.+)]$"); |
| | | private static final String SEQUENCE_SOURCE = "sequence"; |
| | | private static final String SEQUENCE_LABEL = "序号"; |
| | | private static final int EXCEL_WIDTH_UNIT = 256; |
| | | private static final int MIN_COLUMN_WIDTH_CHARS = 8; |
| | | private static final int MAX_COLUMN_WIDTH_CHARS = 60; |
| | | private static final int COLUMN_WIDTH_PADDING_CHARS = 2; |
| | | |
| | | public static void build(Workbook workbook, HttpServletResponse response) { |
| | | response.reset(); |
| | |
| | | } |
| | | } |
| | | } |
| | | for (int i = 0; i <= fields.length; i++) { |
| | | sheet.autoSizeColumn(i); |
| | | } |
| | | autoFitColumns(sheet, headerIdx, 0); |
| | | |
| | | return workbook; |
| | | } |
| | |
| | | } |
| | | } |
| | | |
| | | for (int columnIndex = 0; columnIndex < effectiveColumns.size(); columnIndex++) { |
| | | sheet.autoSizeColumn(columnIndex); |
| | | } |
| | | autoFitColumns(sheet, effectiveColumns.size(), header.getRowNum()); |
| | | |
| | | return workbook; |
| | | } |
| | | |
| | | private static void autoFitColumns(Sheet sheet, int columnCount, int startRowIndex) { |
| | | if (sheet == null || columnCount <= 0) { |
| | | return; |
| | | } |
| | | |
| | | DataFormatter formatter = new DataFormatter(Locale.CHINA); |
| | | for (int columnIndex = 0; columnIndex < columnCount; columnIndex++) { |
| | | int maxDisplayChars = MIN_COLUMN_WIDTH_CHARS; |
| | | for (int rowIndex = Math.max(startRowIndex, 0); rowIndex <= sheet.getLastRowNum(); rowIndex++) { |
| | | Row row = sheet.getRow(rowIndex); |
| | | if (row == null) { |
| | | continue; |
| | | } |
| | | Cell cell = row.getCell(columnIndex); |
| | | if (cell == null || isMergedCell(sheet, rowIndex, columnIndex)) { |
| | | continue; |
| | | } |
| | | maxDisplayChars = Math.max(maxDisplayChars, getDisplayChars(formatter.formatCellValue(cell))); |
| | | } |
| | | int widthChars = Math.min(MAX_COLUMN_WIDTH_CHARS, maxDisplayChars + COLUMN_WIDTH_PADDING_CHARS); |
| | | sheet.setColumnWidth(columnIndex, widthChars * EXCEL_WIDTH_UNIT); |
| | | } |
| | | } |
| | | |
| | | private static boolean isMergedCell(Sheet sheet, int rowIndex, int columnIndex) { |
| | | for (int index = 0; index < sheet.getNumMergedRegions(); index++) { |
| | | CellRangeAddress region = sheet.getMergedRegion(index); |
| | | if (region.isInRange(rowIndex, columnIndex)) { |
| | | return true; |
| | | } |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | private static int getDisplayChars(String value) { |
| | | if (StringUtils.isBlank(value)) { |
| | | return 0; |
| | | } |
| | | int maxLineChars = 0; |
| | | for (String line : value.split("\\R", -1)) { |
| | | maxLineChars = Math.max(maxLineChars, getLineDisplayChars(line)); |
| | | } |
| | | return maxLineChars; |
| | | } |
| | | |
| | | private static int getLineDisplayChars(String value) { |
| | | int width = 0; |
| | | for (int index = 0; index < value.length(); ) { |
| | | int codePoint = value.codePointAt(index); |
| | | width += isWideCodePoint(codePoint) ? 2 : 1; |
| | | index += Character.charCount(codePoint); |
| | | } |
| | | return width; |
| | | } |
| | | |
| | | private static boolean isWideCodePoint(int codePoint) { |
| | | Character.UnicodeScript script = Character.UnicodeScript.of(codePoint); |
| | | return script == Character.UnicodeScript.HAN |
| | | || script == Character.UnicodeScript.HIRAGANA |
| | | || script == Character.UnicodeScript.KATAKANA |
| | | || script == Character.UnicodeScript.HANGUL; |
| | | } |
| | | |
| | | private static List<ExportColumn> buildEffectiveColumns(List<ExportColumn> columns, ExportMeta exportMeta) { |
| | | List<ExportColumn> effectiveColumns = new ArrayList<>(columns); |
| | | if (exportMeta != null && exportMeta.isShowSequence() && !containsSequenceColumn(columns)) { |