package com.engine.jucailinkq.common.util.excel; import com.engine.jucailinkq.common.util.DateUtil; import org.apache.poi.hssf.usermodel.*; import org.apache.poi.ss.usermodel.*; import org.apache.poi.ss.util.CellRangeAddress; import org.apache.poi.ss.util.CellRangeAddressList; import org.apache.poi.xssf.usermodel.*; import java.util.*; import static org.apache.poi.hssf.usermodel.DVConstraint.createExplicitListConstraint; /** * @Author: sy * @Description: * @Date: 2024/6/5 **/ public class ExcelUtil { 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.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) { 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(DateUtil.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, String title, int titleCellNum) { 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); // 合并第一行的前titleCellNum个单元格 CellRangeAddress cellRangeAddress = new CellRangeAddress(0, 0, 0, titleCellNum - 1); sheet.addMergedRegion(cellRangeAddress); //遍历设置列宽 List header = rowList.get(0); for (int i = 0; i < header.size(); i++) { sheet.setColumnWidth(i, Math.max(12, header.get(i).toString().length() * 4) * 256); } for (int rowIndex = 0; rowIndex <= rowList.size(); rowIndex++) { XSSFRow row = sheet.createRow(rowIndex); float height = 18; float finalHeight = 18; if (rowIndex == 0) { XSSFCell cell = row.createCell(0); cell.setCellStyle(titleCellStyle); cell.setCellType(CellType.STRING); cell.setCellValue(title); } else { List infoList = rowList.get(rowIndex - 1); for (int cellIndex = 0; cellIndex < infoList.size(); cellIndex++) { XSSFCell cell = row.createCell(cellIndex); if (rowIndex == 1) { cell.setCellStyle(titleCellStyle); } else { cell.setCellStyle(cellStyle); } Object o = infoList.get(cellIndex); if (o instanceof String) { 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(DateUtil.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 HSSFWorkbook genWorkbookV2WithDropdownList1(List> rowList, String sheetName, String title, int titleCellNum, String[] dropdownData, List deopdownRange) { HSSFWorkbook hssfWorkbook = new HSSFWorkbook(); // 设置title样式 HSSFCellStyle titleCellStyle = hssfWorkbook.createCellStyle(); HSSFFont titleFont = hssfWorkbook.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); // 设置主体样式 HSSFCellStyle cellStyle = hssfWorkbook.createCellStyle(); HSSFFont font = hssfWorkbook.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); HSSFSheet sheet = hssfWorkbook.createSheet(sheetName); //自适应宽度 sheet.autoSizeColumn(0, true); //默认列宽 sheet.setDefaultColumnWidth(20); //默认行高 sheet.setDefaultRowHeightInPoints(18); //设置下拉列表 Map boxMap = new HashMap<>(); boxMap.put("班次名称", String.join(",", dropdownData)); //指定将下拉框添加至1-10行,0-0列。即第一列的第2到11行 HSSFDataValidation dataValidation = createBox("班次名称", boxMap , deopdownRange.get(0), deopdownRange.get(1), deopdownRange.get(2), deopdownRange.get(3)); if(dataValidation != null) { sheet.addValidationData(dataValidation); } sheet.addValidationData(dataValidation); // 合并第一行的前titleCellNum个单元格 CellRangeAddress cellRangeAddress = new CellRangeAddress(0, 0, 0, titleCellNum - 1); sheet.addMergedRegion(cellRangeAddress); //遍历设置列宽 List header = rowList.get(0); for (int i = 0; i < header.size(); i++) { sheet.setColumnWidth(i, Math.max(12, header.get(i).toString().length() * 4) * 256); } for (int rowIndex = 0; rowIndex <= rowList.size(); rowIndex++) { HSSFRow row = sheet.createRow(rowIndex); float height = 18; float finalHeight = 18; if (rowIndex == 0) { HSSFCell cell = row.createCell(0); cell.setCellStyle(titleCellStyle); cell.setCellType(CellType.STRING); cell.setCellValue(title); } else { List infoList = rowList.get(rowIndex - 1); for (int cellIndex = 0; cellIndex < infoList.size(); cellIndex++) { HSSFCell cell = row.createCell(cellIndex); if (rowIndex == 1) { cell.setCellStyle(titleCellStyle); } else { cell.setCellStyle(cellStyle); } Object o = infoList.get(cellIndex); if (o instanceof String) { 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(DateUtil.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 hssfWorkbook; } /** * excel导出,有码值的数据使用下拉框展示。 * @param col 列名 * @param boxMap 码值集合 * @param firstRow 插入下拉框开始行号 * @param lastRow 插入下拉框结束行号 * @param firstCol 插入下拉框开始列号 * @param lastCol 插入下拉框结束行号 * @return */ public static HSSFDataValidation createBox(String col, Map boxMap, int firstRow, int lastRow, int firstCol, int lastCol) { HSSFDataValidation dataValidation = null; //查询码值表,如果长度超过255,则截取 String cols = ""; String completeCols = ""; if(null != boxMap.get(col)) { cols = boxMap.get(col); } completeCols = cols; if (cols.length() > 255) { cols = cols.substring(0, 255); } //设置下拉框 if(cols.length() > 0) { String[] str = cols.split(","); if (completeCols.length() > 255) { String[] completeStr = completeCols.split(","); if (!completeStr[str.length - 1].equals(str[str.length - 1])) { str = Arrays.copyOf(completeStr, str.length - 1); } } //指定firstRow-lastRow行,firstCol-lastCol列为下拉框 CellRangeAddressList cas = new CellRangeAddressList(firstRow , lastRow , firstCol , lastCol); //创建下拉数据列 DVConstraint dvConstraint = DVConstraint.createExplicitListConstraint(str); //将下拉数据放入下拉框 dataValidation = new HSSFDataValidation(cas, dvConstraint); } return dataValidation; } 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; } }