package com.engine.salary.util.excel; import cn.hutool.core.util.StrUtil; import com.engine.salary.component.WeaTableColumnGroup; import com.engine.salary.util.SalaryDateUtil; import org.apache.commons.collections4.CollectionUtils; import org.apache.poi.ss.usermodel.*; import org.apache.poi.ss.util.CellRangeAddress; import org.apache.poi.xssf.usermodel.*; import weaver.wechat.util.Utils; import java.awt.Color; import java.math.BigDecimal; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; public class ExcelUtilPlus { /** * 生成excel * * @param rowList * @return */ public static XSSFWorkbook genWorkbook(List> rowList, String sheetName) { XSSFWorkbook workbook = new XSSFWorkbook(); // 设置title样式 XSSFCellStyle titleCellStyle = workbook.createCellStyle(); XSSFFont titleFont = workbook.createFont(); titleFont.setFontName("仿宋"); titleFont.setFontHeightInPoints((short) 15); titleCellStyle.setFont(titleFont); titleCellStyle.setAlignment(HorizontalAlignment.CENTER); titleCellStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());//背景色 titleCellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); // 设置主体样式 XSSFCellStyle cellStyle = workbook.createCellStyle(); XSSFFont font = workbook.createFont(); font.setFontName("宋体"); font.setFontHeightInPoints((short) 10);// 设置字体大小 cellStyle.setFont(font);// 选择需要用到的字体格式 cellStyle.setWrapText(true); XSSFSheet sheet = workbook.createSheet(sheetName); //自适应宽度 sheet.autoSizeColumn(0, true); //默认列宽 sheet.setDefaultColumnWidth(20); //默认行高 sheet.setDefaultRowHeightInPoints(18); for (int rowIndex = 0; rowIndex < rowList.size(); rowIndex++) { List infoList = rowList.get(rowIndex); XSSFRow row = sheet.createRow(rowIndex); for (int cellIndex = 0; cellIndex < infoList.size(); cellIndex++) { XSSFCell cell = row.createCell(cellIndex); cell.setCellType(CellType.STRING); if (rowIndex == 0) { cell.setCellStyle(titleCellStyle); } else { cell.setCellStyle(cellStyle); } cell.setCellValue(infoList.get(cellIndex)); // sheet.setColumnWidth(cellIndex, 35 * 256); } } return workbook; } public static XSSFWorkbook genWorkbookV2WithPattern(List> rowList, String sheetName, boolean lastRowRed) { XSSFWorkbook workbook = new XSSFWorkbook(); // 设置title样式 XSSFCellStyle titleCellStyle = workbook.createCellStyle(); XSSFFont titleFont = workbook.createFont(); titleFont.setBold(true); titleFont.setFontName("仿宋"); titleFont.setFontHeightInPoints((short) 15); titleCellStyle.setFont(titleFont); titleCellStyle.setAlignment(HorizontalAlignment.CENTER); titleCellStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());//背景色 titleCellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); titleCellStyle.setVerticalAlignment(VerticalAlignment.CENTER); titleCellStyle.setBorderLeft(BorderStyle.THIN); titleCellStyle.setBorderRight(BorderStyle.THIN); titleCellStyle.setBorderTop(BorderStyle.THIN); titleCellStyle.setBorderBottom(BorderStyle.THIN); // 设置主体样式 XSSFCellStyle cellStyle = workbook.createCellStyle(); XSSFFont font = workbook.createFont(); font.setFontName("宋体"); font.setFontHeightInPoints((short) 10);// 设置字体大小 cellStyle.setFont(font);// 选择需要用到的字体格式 cellStyle.setWrapText(true); cellStyle.setBorderLeft(BorderStyle.THIN); cellStyle.setBorderRight(BorderStyle.THIN); cellStyle.setBorderTop(BorderStyle.THIN); cellStyle.setBorderBottom(BorderStyle.THIN); XSSFCellStyle redCellStyle = workbook.createCellStyle(); XSSFFont redFont = workbook.createFont(); redFont.setFontName("宋体"); redFont.setFontHeightInPoints((short) 10);// 设置字体大小 redFont.setColor(new XSSFColor(new Color(0xFF3333), null)); redFont.setBold(true); redCellStyle.setWrapText(true); redCellStyle.setFont(redFont);// 选择需要用到的字体格式 redCellStyle.setBorderLeft(BorderStyle.THIN); redCellStyle.setBorderRight(BorderStyle.THIN); redCellStyle.setBorderTop(BorderStyle.THIN); redCellStyle.setBorderBottom(BorderStyle.THIN); XSSFSheet sheet = workbook.createSheet(sheetName); //自适应宽度 sheet.autoSizeColumn(0, true); //默认列宽 sheet.setDefaultColumnWidth(20); //默认行高 sheet.setDefaultRowHeightInPoints(18); //遍历设置列宽 List header = rowList.get(0); List patternList = new ArrayList<>(); XSSFRow row0 = sheet.createRow(0); for (int i = 0; i < header.size(); i++) { WeaTableColumnGroup columnGroupItem = (WeaTableColumnGroup) header.get(i); XSSFCell rowZeroCell = row0.createCell(i, CellType.STRING); rowZeroCell.setCellValue(columnGroupItem.getText()); rowZeroCell.setCellStyle(titleCellStyle); //设置列宽 sheet.setColumnWidth(i, Math.min(255, Math.max(12, Utils.null2String(columnGroupItem.getText()).length() * 4)) * 256); patternList.add(columnGroupItem.getPattern()); } HashMap numberCellStyleMap = new HashMap(); HashMap numberRedCellStyleMap = new HashMap(); XSSFDataFormat df = workbook.createDataFormat(); patternList.stream().distinct().filter(a -> a != null).forEach(p -> { String start = "0."; if (p == 0) { start = "0"; } XSSFCellStyle numberRedCellStyle = workbook.createCellStyle(); // 不能copy,在excel里编辑时背景变成了黑色 // BeanUtils.copyProperties(redCellStyle, numberRedCellStyle); numberRedCellStyle.setWrapText(true); numberRedCellStyle.setBorderLeft(BorderStyle.THIN); numberRedCellStyle.setBorderRight(BorderStyle.THIN); numberRedCellStyle.setBorderTop(BorderStyle.THIN); numberRedCellStyle.setBorderBottom(BorderStyle.THIN); numberRedCellStyle.setFont(redFont); short format = df.getFormat(start + Stream.generate(() -> "0").limit(p).collect(Collectors.joining()) + "_ "); numberRedCellStyle.setDataFormat(format); numberRedCellStyleMap.put(p, numberRedCellStyle); XSSFCellStyle numberCellStyle = workbook.createCellStyle(); // BeanUtils.copyProperties(cellStyle, numberCellStyle); numberCellStyle.setFont(font);// 选择需要用到的字体格式 numberCellStyle.setWrapText(true); numberCellStyle.setBorderLeft(BorderStyle.THIN); numberCellStyle.setBorderRight(BorderStyle.THIN); numberCellStyle.setBorderTop(BorderStyle.THIN); numberCellStyle.setBorderBottom(BorderStyle.THIN); numberCellStyle.setDataFormat(format); numberCellStyleMap.put(p, numberCellStyle); }); for (int rowIndex = 1; rowIndex < rowList.size(); rowIndex++) { List infoList = rowList.get(rowIndex); XSSFRow row = sheet.createRow(rowIndex); float height = 18; float finalHeight = 18; for (int cellIndex = 0; cellIndex < infoList.size(); cellIndex++) { XSSFCell cell = row.createCell(cellIndex); if (rowIndex == 0) { cell.setCellStyle(titleCellStyle); } else { if (lastRowRed && rowIndex == rowList.size() - 1) { cell.setCellStyle(redCellStyle); } else { cell.setCellStyle(cellStyle); } } Object o = infoList.get(cellIndex); if (o instanceof String) { if (StrUtil.isNotBlank(String.valueOf(o))) { cell.setCellType(CellType.STRING); cell.setCellValue(String.valueOf(o)); } } else if (o instanceof BigDecimal) { if (lastRowRed && rowIndex == rowList.size() - 1) { cell.setCellStyle(numberRedCellStyleMap.get(patternList.get(cellIndex))); } else { cell.setCellStyle(numberCellStyleMap.get(patternList.get(cellIndex))); } cell.setCellType(CellType.NUMERIC); cell.setCellValue(((BigDecimal) o).doubleValue()); } else if (o instanceof Boolean) { cell.setCellType(CellType.BOOLEAN); cell.setCellValue(String.valueOf(o)); } else if (o instanceof Date) { cell.setCellType(CellType.STRING); cell.setCellValue(SalaryDateUtil.getFormatLocalDate((Date) o)); } else { cell.setCellType(CellType.STRING); cell.setCellValue(o == null ? "" : o.toString()); } //判断是否要调整高度 int width = sheet.getColumnWidth(cellIndex) / 256; finalHeight = getFinalHeight(o, width, finalHeight, height); } row.setHeightInPoints(finalHeight); } return workbook; } public static XSSFWorkbook genWorkbookV2(List> rowList, String sheetName) { XSSFWorkbook workbook = new XSSFWorkbook(); // 设置title样式 XSSFCellStyle titleCellStyle = workbook.createCellStyle(); XSSFFont titleFont = workbook.createFont(); titleFont.setBold(true); titleFont.setFontName("仿宋"); titleFont.setFontHeightInPoints((short) 15); titleCellStyle.setFont(titleFont); titleCellStyle.setAlignment(HorizontalAlignment.CENTER); titleCellStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());//背景色 titleCellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); titleCellStyle.setVerticalAlignment(VerticalAlignment.CENTER); titleCellStyle.setBorderLeft(BorderStyle.THIN); titleCellStyle.setBorderRight(BorderStyle.THIN); titleCellStyle.setBorderTop(BorderStyle.THIN); titleCellStyle.setBorderBottom(BorderStyle.THIN); // 设置主体样式 XSSFCellStyle cellStyle = workbook.createCellStyle(); XSSFFont font = workbook.createFont(); font.setFontName("宋体"); font.setFontHeightInPoints((short) 10);// 设置字体大小 cellStyle.setFont(font);// 选择需要用到的字体格式 cellStyle.setWrapText(true); cellStyle.setBorderLeft(BorderStyle.THIN); cellStyle.setBorderRight(BorderStyle.THIN); cellStyle.setBorderTop(BorderStyle.THIN); cellStyle.setBorderBottom(BorderStyle.THIN); XSSFSheet sheet = workbook.createSheet(sheetName); //自适应宽度 sheet.autoSizeColumn(0, true); //默认列宽 sheet.setDefaultColumnWidth(20); //默认行高 sheet.setDefaultRowHeightInPoints(18); //遍历设置列宽 List header = rowList.get(0); for (int i = 0; i < header.size(); i++) { sheet.setColumnWidth(i, Math.min(255, Math.max(12, header.get(i).toString().length() * 4)) * 256); } for (int rowIndex = 0; rowIndex < rowList.size(); rowIndex++) { List infoList = rowList.get(rowIndex); XSSFRow row = sheet.createRow(rowIndex); float height = 18; float finalHeight = 18; for (int cellIndex = 0; cellIndex < infoList.size(); cellIndex++) { XSSFCell cell = row.createCell(cellIndex); if (rowIndex == 0) { cell.setCellStyle(titleCellStyle); } else { cell.setCellStyle(cellStyle); } Object o = infoList.get(cellIndex); if (o instanceof String) { if (StrUtil.isNotBlank(String.valueOf(o))) { cell.setCellType(CellType.STRING); cell.setCellValue(String.valueOf(o)); } } else if (o instanceof BigDecimal) { cell.setCellType(CellType.NUMERIC); cell.setCellValue(((BigDecimal) o).doubleValue()); } else if (o instanceof Boolean) { cell.setCellType(CellType.BOOLEAN); cell.setCellValue(String.valueOf(o)); } else if (o instanceof Date) { cell.setCellType(CellType.STRING); cell.setCellValue(SalaryDateUtil.getFormatLocalDate((Date) o)); } else { cell.setCellType(CellType.STRING); cell.setCellValue(o == null ? "" : o.toString()); } //判断是否要调整高度 int width = sheet.getColumnWidth(cellIndex) / 256; finalHeight = getFinalHeight(o, width, finalHeight, height); } row.setHeightInPoints(finalHeight); } return workbook; } public static XSSFWorkbook genWorkbookV2(List> rowList, String sheetName, List comments) { XSSFWorkbook workbook = new XSSFWorkbook(); // 设置title样式 XSSFCellStyle titleCellStyle = workbook.createCellStyle(); XSSFFont titleFont = workbook.createFont(); titleFont.setBold(true); titleFont.setFontName("仿宋"); titleFont.setFontHeightInPoints((short) 15); titleCellStyle.setFont(titleFont); titleCellStyle.setAlignment(HorizontalAlignment.CENTER); titleCellStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());//背景色 titleCellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); titleCellStyle.setVerticalAlignment(VerticalAlignment.CENTER); titleCellStyle.setBorderLeft(BorderStyle.THIN); titleCellStyle.setBorderRight(BorderStyle.THIN); titleCellStyle.setBorderTop(BorderStyle.THIN); titleCellStyle.setBorderBottom(BorderStyle.THIN); // 设置主体样式 XSSFCellStyle cellStyle = workbook.createCellStyle(); XSSFFont font = workbook.createFont(); font.setFontName("宋体"); font.setFontHeightInPoints((short) 10);// 设置字体大小 cellStyle.setFont(font);// 选择需要用到的字体格式 cellStyle.setWrapText(true); cellStyle.setBorderLeft(BorderStyle.THIN); cellStyle.setBorderRight(BorderStyle.THIN); cellStyle.setBorderTop(BorderStyle.THIN); cellStyle.setBorderBottom(BorderStyle.THIN); XSSFSheet sheet = workbook.createSheet(sheetName); //自适应宽度 sheet.autoSizeColumn(0, true); //默认列宽 sheet.setDefaultColumnWidth(20); //默认行高 sheet.setDefaultRowHeightInPoints(18); //遍历设置列宽 List header = rowList.get(0); for (int i = 0; i < header.size(); i++) { sheet.setColumnWidth(i, Math.min(255, Math.max(12, header.get(i).toString().length() * 4)) * 256); } for (int rowIndex = 0; rowIndex < rowList.size(); rowIndex++) { List infoList = rowList.get(rowIndex); XSSFRow row = sheet.createRow(rowIndex); float height = 18; float finalHeight = 18; for (int cellIndex = 0; cellIndex < infoList.size(); cellIndex++) { XSSFCell cell = row.createCell(cellIndex); if (rowIndex == 0) { cell.setCellStyle(titleCellStyle); } else { cell.setCellStyle(cellStyle); } Object o = infoList.get(cellIndex); if (o instanceof String) { if (StrUtil.isNotBlank(String.valueOf(o))) { cell.setCellType(CellType.STRING); cell.setCellValue(String.valueOf(o)); } } else if (o instanceof Boolean) { cell.setCellType(CellType.BOOLEAN); cell.setCellValue(String.valueOf(o)); } else if (o instanceof Date) { cell.setCellType(CellType.STRING); cell.setCellValue(SalaryDateUtil.getFormatLocalDate((Date) o)); } else { cell.setCellType(CellType.STRING); cell.setCellValue(String.valueOf(o)); } //判断是否要调整高度 int width = sheet.getColumnWidth(cellIndex) / 256; finalHeight = getFinalHeight(o, width, finalHeight, height); } row.setHeightInPoints(finalHeight); } if (CollectionUtils.isNotEmpty(comments)) { for (ExcelComment c : comments) { XSSFDrawing patr = sheet.createDrawingPatriarch(); XSSFComment cellComment = patr.createCellComment(new XSSFClientAnchor(c.dx1, c.dy1, c.dx2, c.dy2, c.col1, c.row1, c.col2, c.row2)); cellComment.setString(c.content); } } return workbook; } public static XSSFWorkbook genWorkbookV2(List> rowList, String sheetName, boolean lastRowRed) { XSSFWorkbook workbook = new XSSFWorkbook(); // 设置title样式 XSSFCellStyle titleCellStyle = workbook.createCellStyle(); XSSFFont titleFont = workbook.createFont(); titleFont.setBold(true); titleFont.setFontName("仿宋"); titleFont.setFontHeightInPoints((short) 15); titleCellStyle.setFont(titleFont); titleCellStyle.setAlignment(HorizontalAlignment.CENTER); titleCellStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());//背景色 titleCellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); titleCellStyle.setVerticalAlignment(VerticalAlignment.CENTER); titleCellStyle.setBorderLeft(BorderStyle.THIN); titleCellStyle.setBorderRight(BorderStyle.THIN); titleCellStyle.setBorderTop(BorderStyle.THIN); titleCellStyle.setBorderBottom(BorderStyle.THIN); // 设置主体样式 XSSFCellStyle cellStyle = workbook.createCellStyle(); XSSFFont font = workbook.createFont(); font.setFontName("宋体"); font.setFontHeightInPoints((short) 10);// 设置字体大小 cellStyle.setFont(font);// 选择需要用到的字体格式 cellStyle.setWrapText(true); cellStyle.setBorderLeft(BorderStyle.THIN); cellStyle.setBorderRight(BorderStyle.THIN); cellStyle.setBorderTop(BorderStyle.THIN); cellStyle.setBorderBottom(BorderStyle.THIN); XSSFCellStyle redCellStyle = workbook.createCellStyle(); XSSFFont redFont = workbook.createFont(); redFont.setFontName("宋体"); redFont.setFontHeightInPoints((short) 10);// 设置字体大小 redFont.setColor(new XSSFColor(new Color(0xFF3333), null)); redFont.setBold(true); redCellStyle.setWrapText(true); redCellStyle.setFont(redFont);// 选择需要用到的字体格式 redCellStyle.setBorderLeft(BorderStyle.THIN); redCellStyle.setBorderRight(BorderStyle.THIN); redCellStyle.setBorderTop(BorderStyle.THIN); redCellStyle.setBorderBottom(BorderStyle.THIN); XSSFSheet sheet = workbook.createSheet(sheetName); //自适应宽度 sheet.autoSizeColumn(0, true); //默认列宽 sheet.setDefaultColumnWidth(20); //默认行高 sheet.setDefaultRowHeightInPoints(18); //遍历设置列宽 List header = rowList.get(0); for (int i = 0; i < header.size(); i++) { sheet.setColumnWidth(i, Math.min(255, Math.max(12, header.get(i).toString().length() * 4)) * 256); } for (int rowIndex = 0; rowIndex < rowList.size(); rowIndex++) { List infoList = rowList.get(rowIndex); XSSFRow row = sheet.createRow(rowIndex); float height = 18; float finalHeight = 18; for (int cellIndex = 0; cellIndex < infoList.size(); cellIndex++) { XSSFCell cell = row.createCell(cellIndex); if (rowIndex == 0) { cell.setCellStyle(titleCellStyle); } else { if (lastRowRed && rowIndex == rowList.size() - 1) { cell.setCellStyle(redCellStyle); } else { cell.setCellStyle(cellStyle); } } Object o = infoList.get(cellIndex); if (o instanceof String) { if (StrUtil.isNotBlank(String.valueOf(o))) { cell.setCellType(CellType.STRING); cell.setCellValue(String.valueOf(o)); } } else if (o instanceof BigDecimal) { cell.setCellType(CellType.NUMERIC); cell.setCellValue(((BigDecimal) o).doubleValue()); } else if (o instanceof Boolean) { cell.setCellType(CellType.BOOLEAN); cell.setCellValue(String.valueOf(o)); } else if (o instanceof Date) { cell.setCellType(CellType.STRING); cell.setCellValue(SalaryDateUtil.getFormatLocalDate((Date) o)); } else { cell.setCellType(CellType.STRING); cell.setCellValue(o == null ? "" : o.toString()); } //判断是否要调整高度 int width = sheet.getColumnWidth(cellIndex) / 256; finalHeight = getFinalHeight(o, width, finalHeight, height); } row.setHeightInPoints(finalHeight); } return workbook; } // 数值项目修改excel单元格格式为数值 public static XSSFWorkbook genWorkbookWithChildTitleColumnWithExcelFormat(List> rowList, String sheetName, boolean lastRowRed) { XSSFWorkbook workbook = new XSSFWorkbook(); // 设置title样式 XSSFCellStyle titleCellStyle = workbook.createCellStyle(); XSSFFont titleFont = workbook.createFont(); titleFont.setBold(true); titleFont.setFontName("仿宋"); titleFont.setFontHeightInPoints((short) 15); titleCellStyle.setFont(titleFont); titleCellStyle.setAlignment(HorizontalAlignment.CENTER); titleCellStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());//背景色 titleCellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); titleCellStyle.setVerticalAlignment(VerticalAlignment.CENTER); titleCellStyle.setBorderLeft(BorderStyle.THIN); titleCellStyle.setBorderRight(BorderStyle.THIN); titleCellStyle.setBorderTop(BorderStyle.THIN); titleCellStyle.setBorderBottom(BorderStyle.THIN); XSSFCellStyle childTitleCellStyle = workbook.createCellStyle(); childTitleCellStyle.setFont(titleFont); childTitleCellStyle.setAlignment(HorizontalAlignment.LEFT); childTitleCellStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());//背景色 childTitleCellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); childTitleCellStyle.setVerticalAlignment(VerticalAlignment.CENTER); childTitleCellStyle.setBorderLeft(BorderStyle.THIN); childTitleCellStyle.setBorderRight(BorderStyle.THIN); childTitleCellStyle.setBorderTop(BorderStyle.THIN); childTitleCellStyle.setBorderBottom(BorderStyle.THIN); // 设置主体样式 XSSFCellStyle cellStyle = workbook.createCellStyle(); XSSFFont font = workbook.createFont(); font.setFontName("宋体"); font.setFontHeightInPoints((short) 10);// 设置字体大小 cellStyle.setFont(font);// 选择需要用到的字体格式 cellStyle.setWrapText(true); cellStyle.setBorderLeft(BorderStyle.THIN); cellStyle.setBorderRight(BorderStyle.THIN); cellStyle.setBorderTop(BorderStyle.THIN); cellStyle.setBorderBottom(BorderStyle.THIN); XSSFCellStyle redCellStyle = workbook.createCellStyle(); XSSFFont redFont = workbook.createFont(); redFont.setFontName("宋体"); redFont.setFontHeightInPoints((short) 10);// 设置字体大小 redFont.setColor(new XSSFColor(new Color(0xFF3333), null)); redFont.setBold(true); redCellStyle.setWrapText(true); redCellStyle.setFont(redFont);// 选择需要用到的字体格式 redCellStyle.setBorderLeft(BorderStyle.THIN); redCellStyle.setBorderRight(BorderStyle.THIN); redCellStyle.setBorderTop(BorderStyle.THIN); redCellStyle.setBorderBottom(BorderStyle.THIN); XSSFSheet sheet = workbook.createSheet(sheetName); //自适应宽度 sheet.autoSizeColumn(0, true); //默认列宽 sheet.setDefaultColumnWidth(20); //默认行高 sheet.setDefaultRowHeightInPoints(18); //处理合并单元格 XSSFRow row0 = sheet.createRow(0); XSSFRow row1 = sheet.createRow(1); // 保留小数位数 List patternList = new ArrayList<>(); List header = rowList.get(0); int startIndex = 0; for (int i = 0; i < header.size(); i++) { WeaTableColumnGroup columnGroupItem = (WeaTableColumnGroup) header.get(i); if (columnGroupItem.getChildren() == null) { sheet.addMergedRegion(new CellRangeAddress(0, 1, startIndex, startIndex)); XSSFCell rowZeroCell = row0.createCell(startIndex, CellType.STRING); rowZeroCell.setCellValue(columnGroupItem.getText().toString()); rowZeroCell.setCellStyle(titleCellStyle); XSSFCell rowOneCell = row1.createCell(startIndex, CellType.STRING); rowOneCell.setCellValue(columnGroupItem.getText().toString()); rowOneCell.setCellStyle(titleCellStyle); //设置列宽 sheet.setColumnWidth(startIndex, Math.min(255, Math.max(12, columnGroupItem.getText().length() * 4)) * 256); startIndex++; patternList.add(columnGroupItem.getPattern()); } else { List childrenList = columnGroupItem.getChildren(); int endIndex = startIndex + childrenList.size() - 1; if (endIndex > startIndex) { sheet.addMergedRegion(new CellRangeAddress(0, 0, startIndex, endIndex)); } XSSFCell cell = row0.createCell(startIndex, CellType.STRING); cell.setCellValue(columnGroupItem.getText().toString()); cell.setCellStyle(childTitleCellStyle); for (int j = 0; j < childrenList.size(); j++) { WeaTableColumnGroup childrenItem = (WeaTableColumnGroup) childrenList.get(j); XSSFCell subHeader = row1.createCell(startIndex + j, CellType.STRING); subHeader.setCellValue(childrenItem.getText().toString()); subHeader.setCellStyle(titleCellStyle); //设置列宽 sheet.setColumnWidth(startIndex + j, Math.min(255, Math.max(12, childrenItem.getText().length() * 4)) * 256); patternList.add(childrenItem.getPattern()); } startIndex += childrenList.size(); } } HashMap numberCellStyleMap = new HashMap(); HashMap numberRedCellStyleMap = new HashMap(); XSSFDataFormat df = workbook.createDataFormat(); patternList.stream().distinct().filter(a -> a != null).forEach(p -> { String start = "0."; if (p == 0) { start = "0"; } XSSFCellStyle numberRedCellStyle = workbook.createCellStyle(); // 不能copy,在excel里编辑时背景变成了黑色 // BeanUtils.copyProperties(redCellStyle, numberRedCellStyle); numberRedCellStyle.setWrapText(true); numberRedCellStyle.setBorderLeft(BorderStyle.THIN); numberRedCellStyle.setBorderRight(BorderStyle.THIN); numberRedCellStyle.setBorderTop(BorderStyle.THIN); numberRedCellStyle.setBorderBottom(BorderStyle.THIN); numberRedCellStyle.setFont(redFont); short format = df.getFormat(start + Stream.generate(() -> "0").limit(p).collect(Collectors.joining()) + "_ "); numberRedCellStyle.setDataFormat(format); // 最后一行红色 numberRedCellStyleMap.put(p, numberRedCellStyle); XSSFCellStyle numberCellStyle = workbook.createCellStyle(); // BeanUtils.copyProperties(cellStyle, numberCellStyle); numberCellStyle.setFont(font);// 选择需要用到的字体格式 numberCellStyle.setWrapText(true); numberCellStyle.setBorderLeft(BorderStyle.THIN); numberCellStyle.setBorderRight(BorderStyle.THIN); numberCellStyle.setBorderTop(BorderStyle.THIN); numberCellStyle.setBorderBottom(BorderStyle.THIN); numberCellStyle.setDataFormat(format); numberCellStyleMap.put(p, numberCellStyle); }); for (int rowIndex = 1; rowIndex < rowList.size(); rowIndex++) { List infoList = rowList.get(rowIndex); XSSFRow row = sheet.createRow(rowIndex + 1); float height = 18; float finalHeight = 18; for (int cellIndex = 0; cellIndex < infoList.size(); cellIndex++) { XSSFCell cell = row.createCell(cellIndex); if (rowIndex == 0) { cell.setCellStyle(titleCellStyle); } else { if (lastRowRed && rowIndex == rowList.size() - 1) { cell.setCellStyle(redCellStyle); } else { cell.setCellStyle(cellStyle); } } Object o = infoList.get(cellIndex); if (o instanceof String) { if (StrUtil.isNotBlank(String.valueOf(o))) { cell.setCellType(CellType.STRING); cell.setCellValue(String.valueOf(o)); } } else if (o instanceof BigDecimal) { if (lastRowRed && rowIndex == rowList.size() - 1) { cell.setCellStyle(numberRedCellStyleMap.get(patternList.get(cellIndex))); } else { cell.setCellStyle(numberCellStyleMap.get(patternList.get(cellIndex))); } cell.setCellType(CellType.NUMERIC); double value = o == null ? 0 : ((BigDecimal) o).doubleValue(); cell.setCellValue(value); } else if (o instanceof Boolean) { cell.setCellType(CellType.BOOLEAN); cell.setCellValue(String.valueOf(o)); } else if (o instanceof Date) { cell.setCellType(CellType.STRING); cell.setCellValue(SalaryDateUtil.getFormatLocalDate((Date) o)); } else { cell.setCellType(CellType.STRING); cell.setCellValue(o == null ? "" : o.toString()); } //判断是否要调整高度 int width = sheet.getColumnWidth(cellIndex) / 256; finalHeight = getFinalHeight(o, width, finalHeight, height); } row.setHeightInPoints(finalHeight); } return workbook; } public static XSSFWorkbook genWorkbookWithChildTitleColumn(List> rowList, String sheetName, boolean lastRowRed) { XSSFWorkbook workbook = new XSSFWorkbook(); // 设置title样式 XSSFCellStyle titleCellStyle = workbook.createCellStyle(); XSSFFont titleFont = workbook.createFont(); titleFont.setBold(true); titleFont.setFontName("仿宋"); titleFont.setFontHeightInPoints((short) 15); titleCellStyle.setFont(titleFont); titleCellStyle.setAlignment(HorizontalAlignment.CENTER); titleCellStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());//背景色 titleCellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); titleCellStyle.setVerticalAlignment(VerticalAlignment.CENTER); titleCellStyle.setBorderLeft(BorderStyle.THIN); titleCellStyle.setBorderRight(BorderStyle.THIN); titleCellStyle.setBorderTop(BorderStyle.THIN); titleCellStyle.setBorderBottom(BorderStyle.THIN); XSSFCellStyle childTitleCellStyle = workbook.createCellStyle(); childTitleCellStyle.setFont(titleFont); childTitleCellStyle.setAlignment(HorizontalAlignment.LEFT); childTitleCellStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());//背景色 childTitleCellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); childTitleCellStyle.setVerticalAlignment(VerticalAlignment.CENTER); childTitleCellStyle.setBorderLeft(BorderStyle.THIN); childTitleCellStyle.setBorderRight(BorderStyle.THIN); childTitleCellStyle.setBorderTop(BorderStyle.THIN); childTitleCellStyle.setBorderBottom(BorderStyle.THIN); // 设置主体样式 XSSFCellStyle cellStyle = workbook.createCellStyle(); XSSFFont font = workbook.createFont(); font.setFontName("宋体"); font.setFontHeightInPoints((short) 10);// 设置字体大小 cellStyle.setFont(font);// 选择需要用到的字体格式 cellStyle.setWrapText(true); cellStyle.setBorderLeft(BorderStyle.THIN); cellStyle.setBorderRight(BorderStyle.THIN); cellStyle.setBorderTop(BorderStyle.THIN); cellStyle.setBorderBottom(BorderStyle.THIN); cellStyle.setFillPattern(FillPatternType.NO_FILL); XSSFCellStyle redCellStyle = workbook.createCellStyle(); XSSFFont redFont = workbook.createFont(); redFont.setFontName("宋体"); redFont.setFontHeightInPoints((short) 10);// 设置字体大小 redFont.setColor(new XSSFColor(new Color(0xFF3333), null)); redFont.setBold(true); redCellStyle.setWrapText(true); redCellStyle.setFont(redFont);// 选择需要用到的字体格式 redCellStyle.setBorderLeft(BorderStyle.THIN); redCellStyle.setBorderRight(BorderStyle.THIN); redCellStyle.setBorderTop(BorderStyle.THIN); redCellStyle.setBorderBottom(BorderStyle.THIN); XSSFSheet sheet = workbook.createSheet(sheetName); //自适应宽度 sheet.autoSizeColumn(0, true); //默认列宽 sheet.setDefaultColumnWidth(20); //默认行高 sheet.setDefaultRowHeightInPoints(18); //处理合并单元格 XSSFRow row0 = sheet.createRow(0); XSSFRow row1 = sheet.createRow(1); List header = rowList.get(0); int startIndex = 0; for (int i = 0; i < header.size(); i++) { WeaTableColumnGroup columnGroupItem = (WeaTableColumnGroup) header.get(i); if (columnGroupItem.getChildren() == null) { sheet.addMergedRegion(new CellRangeAddress(0, 1, startIndex, startIndex)); XSSFCell rowZeroCell = row0.createCell(startIndex, CellType.STRING); rowZeroCell.setCellValue(columnGroupItem.getText().toString()); rowZeroCell.setCellStyle(titleCellStyle); XSSFCell rowOneCell = row1.createCell(startIndex, CellType.STRING); rowOneCell.setCellValue(columnGroupItem.getText().toString()); rowOneCell.setCellStyle(titleCellStyle); //设置列宽 sheet.setColumnWidth(startIndex, Math.min(255, Math.max(12, columnGroupItem.getText().length() * 4)) * 256); startIndex++; } else { List childrenList = columnGroupItem.getChildren(); int endIndex = startIndex + childrenList.size() - 1; if (endIndex > startIndex) { sheet.addMergedRegion(new CellRangeAddress(0, 0, startIndex, endIndex)); } XSSFCell cell = row0.createCell(startIndex, CellType.STRING); cell.setCellValue(columnGroupItem.getText().toString()); cell.setCellStyle(childTitleCellStyle); for (int j = 0; j < childrenList.size(); j++) { WeaTableColumnGroup childrenItem = (WeaTableColumnGroup) childrenList.get(j); XSSFCell subHeader = row1.createCell(startIndex + j, CellType.STRING); subHeader.setCellValue(childrenItem.getText().toString()); subHeader.setCellStyle(titleCellStyle); //设置列宽 sheet.setColumnWidth(startIndex + j, Math.min(255, Math.max(12, childrenItem.getText().length() * 4)) * 256); } startIndex += childrenList.size(); } } for (int rowIndex = 1; rowIndex < rowList.size(); rowIndex++) { List infoList = rowList.get(rowIndex); XSSFRow row = sheet.createRow(rowIndex + 1); float height = 18; float finalHeight = 18; for (int cellIndex = 0; cellIndex < infoList.size(); cellIndex++) { XSSFCell cell = row.createCell(cellIndex); if (rowIndex == 0) { cell.setCellStyle(titleCellStyle); } else { if (lastRowRed && rowIndex == rowList.size() - 1) { cell.setCellStyle(redCellStyle); } else { cell.setCellStyle(cellStyle); } } Object o = infoList.get(cellIndex); if (o instanceof String) { if (StrUtil.isNotBlank(String.valueOf(o))) { cell.setCellType(CellType.STRING); cell.setCellValue(String.valueOf(o)); } } else if (o instanceof BigDecimal) { cell.setCellType(CellType.NUMERIC); cell.setCellValue(o == null ? 0 : ((BigDecimal) o).doubleValue()); } else if (o instanceof Boolean) { cell.setCellType(CellType.BOOLEAN); cell.setCellValue(String.valueOf(o)); } else if (o instanceof Date) { cell.setCellType(CellType.STRING); cell.setCellValue(SalaryDateUtil.getFormatLocalDate((Date) o)); } else { cell.setCellType(CellType.STRING); cell.setCellValue(o == null ? "" : o.toString()); } //判断是否要调整高度 int width = sheet.getColumnWidth(cellIndex) / 256; finalHeight = getFinalHeight(o, width, finalHeight, height); } row.setHeightInPoints(finalHeight); } return workbook; } public static float getFinalHeight(Object o, int width, float finalHeight, float height) { if (o != null && getStrlength(o.toString()) > width) { float remainder = getStrlength(o.toString()) % width; int multiple = getStrlength(o.toString()) / width; int finalMultiple = remainder > 0 ? (multiple + 1) : multiple; float compareHeight = height * finalMultiple; finalHeight = Math.max(finalHeight, compareHeight); } return finalHeight; } public static int getStrlength(String str) { int strLength = 0; String chinese = "[\u0391-\uFFE5]"; /* 获取字段值的长度,如果含中文字符,则每个中文字符长度为2,否则为1 */ for (int i = 0; i < str.length(); i++) { /* 从字符串中获取一个字符 */ String temp = str.substring(i, i + 1); /* 判断是否为中文字符 */ if (temp.matches(chinese)) { /* 中文字符长度为2 */ strLength += 2; } else { /* 其他字符长度为1 */ strLength += 1; } } return strLength; } }