package com.doumee.core.annotation.excel; import com.doumee.core.constants.Constants; import com.doumee.core.constants.ResponseStatus; import com.doumee.core.exception.BusinessException; import com.doumee.dao.business.model.Goodsorder; import lombok.AllArgsConstructor; import lombok.Data; import org.apache.poi.ss.usermodel.*; import org.apache.poi.ss.util.CellRangeAddress; import org.apache.poi.xssf.streaming.SXSSFWorkbook; import org.springframework.core.annotation.AnnotationConfigurationException; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.OutputStream; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.net.URLEncoder; import java.nio.charset.Charset; import java.text.SimpleDateFormat; import java.util.*; /** * Excel导出实现 * @author Eva.Caesar Liu * @date 2023/02/14 11:14 */ @Data public class ExcelExporter { private static final String DEFAULT_SHEET_NAME = "Sheet1"; private Class modelClass; private ExcelExporter(){} /** * 构造器 * @param modelClass 实体Class对象 */ public static ExcelExporter build(Class modelClass) { ExcelExporter excelExporter = new ExcelExporter<>(); excelExporter.setModelClass(modelClass); return excelExporter; } /** * 导出到指定输出流 * @param data 数据 * @param sheetName Sheet名称 */ public void exportWithFirstAndEnd (List data, String sheetName,String first,String end, OutputStream os) { SXSSFWorkbook sxssfWorkbook; try { sxssfWorkbook = new SXSSFWorkbook(); Sheet sheet = sxssfWorkbook.createSheet(sheetName); // 创建列头 sheet.createFreezePane(0, 2); sheet.addMergedRegion(new CellRangeAddress(0 ,0,0,this.getColumns().size()-1)); Row title = sheet.createRow(0); title.setHeight((short) 1000); Cell c = title.createCell(0); c.setCellValue(first); configFirstCell(sxssfWorkbook,c); Row header = sheet.createRow(1); List columns = this.getColumns(); for (int columnIndex = 0; columnIndex < columns.size(); columnIndex++) { ColumnInfo column = columns.get(columnIndex); Cell cell = header.createCell(columnIndex); cell.setCellValue(column.columnConfig.name()); // 列宽设置 if (column.columnConfig.width() == -1) { sheet.setColumnWidth(columnIndex, column.columnConfig.name().length() * 2 * 256); } else { sheet.setColumnWidth(columnIndex, column.columnConfig.width() * 2 * 256); } // 设置列头单元格 configHeaderCell(sxssfWorkbook, cell, column.columnConfig); } // 创建数据记录 for (int rowIndex = 0; rowIndex < data.size(); rowIndex++) { Row row = sheet.createRow(rowIndex + 2); for (int columnIndex = 0; columnIndex < columns.size(); columnIndex++) { ColumnInfo column = columns.get(columnIndex); Cell cell = row.createCell(columnIndex); cell.setCellValue(getCellData(column, data.get(rowIndex))); // 设置数据单元格 configDataCell(sxssfWorkbook, cell, column.columnConfig); } } sheet.addMergedRegion(new CellRangeAddress(data.size()+2 ,data.size()+2,0,this.getColumns().size()-1)); Row endRow = sheet.createRow(data.size()+2); // endRow.setHeight((short) 600); Cell c1 = endRow.createCell(0); c1.setCellValue(end); configEndCell(sxssfWorkbook,c1); sxssfWorkbook.write(os); os.close(); } catch (Exception e) { throw new BusinessException(ResponseStatus.EXPORT_EXCEL_ERROR, e); } finally { if (os != null) { try { os.close(); } catch (IOException e) { e.printStackTrace(); } } } } /** * 导出到指定输出流 * @param data 数据 * @param sheetName Sheet名称 * @param os 输出流 */ public void export (List data, String sheetName, OutputStream os) { SXSSFWorkbook sxssfWorkbook; try { sxssfWorkbook = new SXSSFWorkbook(); Sheet sheet = sxssfWorkbook.createSheet(sheetName); // 创建列头 sheet.createFreezePane(0, 1); Row header = sheet.createRow(0); List columns = this.getColumns(); for (int columnIndex = 0; columnIndex < columns.size(); columnIndex++) { ColumnInfo column = columns.get(columnIndex); Cell cell = header.createCell(columnIndex); cell.setCellValue(column.columnConfig.name()); // 列宽设置 if (column.columnConfig.width() == -1) { sheet.setColumnWidth(columnIndex, column.columnConfig.name().length() * 2 * 256); } else { sheet.setColumnWidth(columnIndex, column.columnConfig.width() * 2 * 256); } // 设置列头单元格 configHeaderCell(sxssfWorkbook, cell, column.columnConfig); } // 创建数据记录 for (int rowIndex = 0; rowIndex < data.size(); rowIndex++) { Row row = sheet.createRow(rowIndex + 1); for (int columnIndex = 0; columnIndex < columns.size(); columnIndex++) { ColumnInfo column = columns.get(columnIndex); Cell cell = row.createCell(columnIndex); cell.setCellValue(getCellData(column, data.get(rowIndex))); // 设置数据单元格 configDataCell(sxssfWorkbook, cell, column.columnConfig); } } sxssfWorkbook.write(os); os.close(); } catch (Exception e) { throw new BusinessException(ResponseStatus.EXPORT_EXCEL_ERROR, e); } finally { if (os != null) { try { os.close(); } catch (IOException e) { e.printStackTrace(); } } } } // public void exportList (List> data, String fileName, String sheetName, HttpServletResponse response) { // try { // String encodeFileName = URLEncoder.encode(fileName, Charset.forName("UTF-8").toString()) + ".xlsx"; // response.setHeader("Content-Disposition","attachment;filename=" + encodeFileName); // response.setContentType("application/octet-stream"); // response.setHeader("eva-opera-type", "download"); // response.setHeader("eva-download-filename", encodeFileName); // this.exportList(data, sheetName, response.getOutputStream()); // } catch (IOException e) { // throw new BusinessException(ResponseStatus.EXPORT_EXCEL_ERROR, e); // } // } /** * 导出到指定输出流 * @param os 输出流 */ public static void exportList (List> dataList ,String sheetName, OutputStream os) { SXSSFWorkbook sxssfWorkbook; try { sxssfWorkbook = new SXSSFWorkbook(); Sheet sheet = sxssfWorkbook.createSheet(sheetName); // 创建列头 sheet.createFreezePane(0, 1); Row header = sheet.createRow(0); CellStyle hstyle = configHeaderCellStatic(sxssfWorkbook); for (int i = 0; i < dataList.size(); i++) { Cell cell = header.createCell(i); cell.setCellValue(dataList.get(i).get(Constants.ZERO)); // 列宽设置 sheet.setColumnWidth(i, dataList.get(i).get(Constants.ZERO).length() * 2 * 256); // 设置列头单元格 cell.setCellStyle(hstyle); } //总行数 Integer rowSize = dataList.get(Constants.ZERO).size(); //总列数 Integer columnSize = dataList.size(); for (int i = 1; i < rowSize; i++) { Row row = sheet.createRow(i); for (int j = 0; j < columnSize; j++) { Cell cell = row.createCell(j); cell.setCellValue(dataList.get(j).get(i)); } } // // List headerList =dataList.get(0); // for (int i = 0; i < headerList.size(); i++) { // Cell cell = header.createCell(i); // cell.setCellValue(headerList.get(i)); // // 列宽设置 // sheet.setColumnWidth(i, headerList.get(i).length() * 2 * 256); // // 设置列头单元格 // cell.setCellStyle(hstyle); // } // // 创建数据记录 // for (int rowIndex = 1; rowIndex < dataList.size(); rowIndex++) { // Row row = sheet.createRow(rowIndex ); // List rowList = dataList.get(rowIndex); // for (int i = 0; i < rowList.size(); i++) { // Cell cell = row.createCell(i); // cell.setCellValue(rowList.get(i)); // // 列宽设置 // cell.setCellStyle(cstyle); // } // } sxssfWorkbook.write(os); os.close(); } catch (Exception e) { throw new BusinessException(ResponseStatus.EXPORT_EXCEL_ERROR, e); } finally { if (os != null) { try { os.close(); } catch (IOException e) { e.printStackTrace(); } } } } /** * 导出至响应流 * @param data 数据 * @param fileName Excel文件名 * @param sheetName Sheet名称 * @param response HttpServletResponse对象 */ public void export (List data, String fileName, String sheetName, HttpServletResponse response) { try { String encodeFileName = URLEncoder.encode(fileName, Charset.forName("UTF-8").toString()) + ".xlsx"; response.setHeader("Content-Disposition","attachment;filename=" + encodeFileName); response.setContentType("application/octet-stream"); response.setHeader("eva-opera-type", "download"); response.setHeader("eva-download-filename", encodeFileName); this.export(data, sheetName, response.getOutputStream()); } catch (IOException e) { throw new BusinessException(ResponseStatus.EXPORT_EXCEL_ERROR, e); } } /** * 导出至响应流 * @param data 数据 * @param fileName Excel文件名 * @param sheetName Sheet名称 * @param response HttpServletResponse对象 */ public void exportWithFirstAndEnd (List data, String fileName, String sheetName, String first,String end ,HttpServletResponse response) { try { String encodeFileName = URLEncoder.encode(fileName, Charset.forName("UTF-8").toString()) + ".xlsx"; response.setHeader("Content-Disposition","attachment;filename=" + encodeFileName); response.setContentType("application/octet-stream"); response.setHeader("eva-opera-type", "download"); response.setHeader("eva-download-filename", encodeFileName); this.exportWithFirstAndEnd(data, sheetName,first,end, response.getOutputStream()); } catch (IOException e) { throw new BusinessException(ResponseStatus.EXPORT_EXCEL_ERROR, e); } } /** * 导出至响应流 * @param data 数据 * @param fileName Excel文件名 * @param response HttpServletResponse对象 */ public void export (List data, String fileName, HttpServletResponse response) { this.export(data, fileName, DEFAULT_SHEET_NAME, response); } /** * 导出至响应流 * @param data 数据 * @param fileName Excel文件名 * @param response HttpServletResponse对象 */ public void exportWithFirstAndEnd (List data, String fileName,String first,String end, HttpServletResponse response) { this.exportWithFirstAndEnd(data, fileName, DEFAULT_SHEET_NAME, first,end,response); } /**O * 获取列集合 */ private List getColumns () { Map sortedFields = new TreeMap<>(); Field[] fields = modelClass.getDeclaredFields(); int index = 0; for (Field field : fields) { ExcelColumn excelColumn = field.getAnnotation(ExcelColumn.class); if (excelColumn == null) { continue; } if (sortedFields.get(excelColumn.index()) != null) { throw new AnnotationConfigurationException("Excel column contains the same index."); } sortedFields.put(excelColumn.index() == -1 ? index : excelColumn.index(), new ColumnInfo(excelColumn, field)); index++; } return new ArrayList<>(sortedFields.values()); } /** * 配置数据单元格 */ private void configDataCell (SXSSFWorkbook workbook, Cell cell, ExcelColumn columnConfig) { CellStyle style = workbook.createCellStyle(); style.setAlignment(columnConfig.align()); style.setVerticalAlignment(VerticalAlignment.CENTER); // 设置背景 style.setFillPattern(FillPatternType.SOLID_FOREGROUND); style.setFillForegroundColor(columnConfig.dataBackgroundColor().getIndex()); // 字体 Font font = workbook.createFont(); font.setFontHeightInPoints(columnConfig.fontSize()); // 字体颜色 font.setColor(columnConfig.color().getIndex()); // 粗体 font.setBold(columnConfig.bold()); // 斜体 font.setItalic(columnConfig.italic()); style.setFont(font); // 边框 configCellBorder(style); style.setWrapText(true); cell.setCellStyle(style); } /** * 配置列头单元格 */ private void configHeaderCell (SXSSFWorkbook workbook, Cell cell, ExcelColumn columnConfig) { CellStyle style = workbook.createCellStyle(); style.setAlignment(columnConfig.align()); style.setVerticalAlignment(VerticalAlignment.CENTER); // 设置背景 style.setFillPattern(FillPatternType.SOLID_FOREGROUND); style.setFillForegroundColor(columnConfig.backgroundColor().getIndex()); // 字体 Font font = workbook.createFont(); font.setFontHeightInPoints(columnConfig.fontSize()); style.setFont(font); // 设置边框 configCellBorder(style); cell.setCellStyle(style); } private static CellStyle configHeaderCellStatic (SXSSFWorkbook workbook) { CellStyle style = workbook.createCellStyle(); style.setAlignment(HorizontalAlignment.CENTER); style.setVerticalAlignment(VerticalAlignment.CENTER); // 设置背景 style.setFillPattern(FillPatternType.SOLID_FOREGROUND); style.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex()); // 字体 Font font = workbook.createFont(); font.setFontHeightInPoints((short) 12); style.setFont(font); // 设置边框 configCellBorder(style); return style; } private static CellStyle configCellStatic (SXSSFWorkbook workbook) { CellStyle style = workbook.createCellStyle(); style.setAlignment(HorizontalAlignment.CENTER); style.setVerticalAlignment(VerticalAlignment.CENTER); // 设置背景 style.setFillPattern(FillPatternType.SOLID_FOREGROUND); // 字体 Font font = workbook.createFont(); font.setFontHeightInPoints((short) 12); style.setFont(font); // 设置边框 configCellBorder(style); return style; } /** * 配置列头单元格 */ private void configFirstCell (SXSSFWorkbook workbook, Cell cell ) { CellStyle style = workbook.createCellStyle(); style.setAlignment(HorizontalAlignment.CENTER); style.setVerticalAlignment(VerticalAlignment.CENTER); // 设置背景 style.setFillPattern(FillPatternType.SOLID_FOREGROUND); style.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex()); // 字体 Font font = workbook.createFont(); font.setFontHeightInPoints((short)18); style.setFont(font); // 设置边框 configCellBorder(style); cell.setCellStyle(style); } /** * 配置列头单元格 */ private void configEndCell (SXSSFWorkbook workbook, Cell cell ) { CellStyle style = workbook.createCellStyle(); style.setAlignment(HorizontalAlignment.RIGHT); style.setVerticalAlignment(VerticalAlignment.CENTER); // 设置背景 style.setFillPattern(FillPatternType.SOLID_FOREGROUND); style.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex()); // 字体 Font font = workbook.createFont(); font.setFontHeightInPoints((short)14); style.setFont(font); // 设置边框 configCellBorder(style); cell.setCellStyle(style); } /** * 配置单元格边框 */ private static void configCellBorder (CellStyle style) { style.setBorderTop(BorderStyle.THIN); style.setBorderRight(BorderStyle.THIN); style.setBorderBottom(BorderStyle.THIN); style.setBorderLeft(BorderStyle.THIN); style.setTopBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); style.setRightBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); style.setBottomBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); style.setLeftBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); } /** * 处理单元格数据 */ private String getCellData (ColumnInfo columnInfo, T row) throws Exception { columnInfo.field.setAccessible(Boolean.TRUE); Object value = columnInfo.field.get(row); columnInfo.field.setAccessible(Boolean.FALSE); if (value == null) { return ""; } String stringValue = value.toString(); // 存在自定义数据处理器 if (!columnInfo.columnConfig.handler().equals(ExcelDataHandlerAdapter.class)) { try { Object instance = columnInfo.columnConfig.handler().newInstance(); Method formatMethod = columnInfo.columnConfig.handler().getMethod("format", Object[].class); List args = new ArrayList<>(); args.add(value); for (String arg : columnInfo.columnConfig.args()) { args.add(arg); } value = formatMethod.invoke(instance, new Object[]{args.toArray()}); stringValue = value.toString(); } catch (Exception e) { throw new IllegalStateException("Can not format data by " + columnInfo.columnConfig.handler(), e); } } // 日期处理 if (!"".equals(columnInfo.columnConfig.dateFormat()) && value instanceof Date) { SimpleDateFormat sdf = new SimpleDateFormat(columnInfo.columnConfig.dateFormat()); stringValue = sdf.format((Date) value); } // 值映射 if (!"".equals(columnInfo.columnConfig.valueMapping())) { String[] segs = columnInfo.columnConfig.valueMapping().split(";"); for (String seg : segs) { String[] mapping = seg.split("="); if (value.toString().equals(mapping[0].trim())) { stringValue = mapping[1].trim(); } } } // 前缀处理 stringValue = columnInfo.columnConfig.prefix() + stringValue; // 后缀处理 stringValue = stringValue + columnInfo.columnConfig.suffix(); return stringValue; } @Data @AllArgsConstructor private static class ColumnInfo { private ExcelColumn columnConfig; private Field field; } }