diff --git a/src/main/java/com/company/agentfoundation/report/ExcelReportService.java b/src/main/java/com/company/agentfoundation/report/ExcelReportService.java index af08070..27dda55 100644 --- a/src/main/java/com/company/agentfoundation/report/ExcelReportService.java +++ b/src/main/java/com/company/agentfoundation/report/ExcelReportService.java @@ -51,7 +51,7 @@ public class ExcelReportService { nullableNumber(row, 6, alert.get("absenceCount"), styles.integer()); cell(row, 7, first(text(alert, "advisorName"), text(alert, "coachName")), styles.body()); } - configureTable(summary, 0, Math.max(rowIndex - 1, 0), headers.length, styles); + configureTable(summary, 0, Math.max(rowIndex - 1, 0), headers.length); widths(summary, 8, 10, 26, 16, 16, 12, 12, 12, 18); return bytes(workbook); } catch (IOException exception) { @@ -103,45 +103,67 @@ public class ExcelReportService { number(row, 11, numberValue(value.get("issueCount")), styles.integer()); number(row, 12, numberValue(value.get("sensitiveHitCount")), styles.integer()); } - configureTable(sheet, 0, rowIndex - 1, headers.length, styles); + configureTable(sheet, 0, rowIndex - 1, headers.length); widths(sheet, 13, 28, 16, 12, 12, 12, 16, 12, 16, 12, 16, 12, 12, 14); } - private void configureTable(Sheet sheet, int headerRow, int lastRow, int columns, Styles styles) { + private void configureTable(Sheet sheet, int headerRow, int lastRow, int columns) { + sheet.setZoom(90); + sheet.setDefaultRowHeightInPoints(22); sheet.createFreezePane(0, headerRow + 1); if (lastRow >= headerRow) sheet.setAutoFilter(new CellRangeAddress(headerRow, lastRow, 0, columns - 1)); - for (int rowIndex = headerRow + 1; rowIndex <= lastRow; rowIndex++) { - Row row = sheet.getRow(rowIndex); - if (row == null) continue; - for (int column = 0; column < columns; column++) { - Cell cell = row.getCell(column); - if (cell != null && rowIndex % 2 == 0 && cell.getCellStyle() == styles.body()) { - cell.setCellStyle(styles.alternate()); - } - } - } + Row header = sheet.getRow(headerRow); + if (header != null) header.setHeightInPoints(27); } private Styles styles(Workbook workbook) { Font headerFont = workbook.createFont(); - headerFont.setBold(true); headerFont.setColor(IndexedColors.WHITE.getIndex()); + headerFont.setFontName("Microsoft YaHei"); + headerFont.setFontHeightInPoints((short) 10); + headerFont.setBold(true); + headerFont.setColor(IndexedColors.WHITE.getIndex()); CellStyle header = workbook.createCellStyle(); - header.setFillForegroundColor(IndexedColors.BLUE_GREY.getIndex()); + header.setFillForegroundColor(IndexedColors.DARK_BLUE.getIndex()); header.setFillPattern(FillPatternType.SOLID_FOREGROUND); - header.setFont(headerFont); header.setAlignment(HorizontalAlignment.CENTER); - header.setBorderBottom(BorderStyle.THIN); + header.setFont(headerFont); + header.setAlignment(HorizontalAlignment.CENTER); + header.setVerticalAlignment(org.apache.poi.ss.usermodel.VerticalAlignment.CENTER); + applyBorders(header, IndexedColors.BLUE_GREY.getIndex()); + Font bodyFont = workbook.createFont(); + bodyFont.setFontName("Microsoft YaHei"); + bodyFont.setFontHeightInPoints((short) 10); CellStyle body = workbook.createCellStyle(); + body.setFont(bodyFont); + body.setAlignment(HorizontalAlignment.LEFT); body.setVerticalAlignment(org.apache.poi.ss.usermodel.VerticalAlignment.CENTER); - CellStyle alternate = workbook.createCellStyle(); - alternate.cloneStyleFrom(body); - alternate.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex()); - alternate.setFillPattern(FillPatternType.SOLID_FOREGROUND); + applyBorders(body, IndexedColors.GREY_40_PERCENT.getIndex()); - CellStyle integer = workbook.createCellStyle(); integer.setDataFormat(workbook.createDataFormat().getFormat("#,##0")); - CellStyle decimal = workbook.createCellStyle(); decimal.setDataFormat(workbook.createDataFormat().getFormat("#,##0.0")); - CellStyle percent = workbook.createCellStyle(); percent.setDataFormat(workbook.createDataFormat().getFormat("0.0%")); - return new Styles(header, body, alternate, integer, decimal, percent); + CellStyle integer = numericStyle(workbook, bodyFont, "#,##0"); + CellStyle decimal = numericStyle(workbook, bodyFont, "#,##0.0"); + CellStyle percent = numericStyle(workbook, bodyFont, "0.0%"); + return new Styles(header, body, integer, decimal, percent); + } + + private CellStyle numericStyle(Workbook workbook, Font font, String numberFormat) { + CellStyle style = workbook.createCellStyle(); + style.setFont(font); + style.setAlignment(HorizontalAlignment.RIGHT); + style.setVerticalAlignment(org.apache.poi.ss.usermodel.VerticalAlignment.CENTER); + style.setDataFormat(workbook.createDataFormat().getFormat(numberFormat)); + applyBorders(style, IndexedColors.GREY_40_PERCENT.getIndex()); + return style; + } + + private void applyBorders(CellStyle style, short color) { + style.setBorderTop(BorderStyle.THIN); + style.setBorderBottom(BorderStyle.THIN); + style.setBorderLeft(BorderStyle.THIN); + style.setBorderRight(BorderStyle.THIN); + style.setTopBorderColor(color); + style.setBottomBorderColor(color); + style.setLeftBorderColor(color); + style.setRightBorderColor(color); } private void cell(Row row, int column, String value, CellStyle style) { @@ -218,7 +240,6 @@ public class ExcelReportService { private record Styles( CellStyle header, CellStyle body, - CellStyle alternate, CellStyle integer, CellStyle decimal, CellStyle percent diff --git a/src/test/java/com/company/agentfoundation/report/ExcelReportServiceTest.java b/src/test/java/com/company/agentfoundation/report/ExcelReportServiceTest.java index 6af02a8..eceb965 100644 --- a/src/test/java/com/company/agentfoundation/report/ExcelReportServiceTest.java +++ b/src/test/java/com/company/agentfoundation/report/ExcelReportServiceTest.java @@ -1,6 +1,9 @@ package com.company.agentfoundation.report; +import org.apache.poi.ss.usermodel.BorderStyle; import org.apache.poi.ss.usermodel.CellType; +import org.apache.poi.ss.usermodel.FillPatternType; +import org.apache.poi.ss.usermodel.IndexedColors; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.junit.jupiter.api.Test; @@ -34,6 +37,9 @@ class ExcelReportServiceTest { .isEqualTo("浦东金桥-跃动运动馆"); assertThat(workbook.getSheetAt(0).getRow(1).getCell(4).getCellType()).isEqualTo(CellType.NUMERIC); assertThat(workbook.getSheetAt(0).getRow(1).getCell(4).getNumericCellValue()).isEqualTo(8.5D); + assertThat(workbook.getSheetAt(0).getRow(0).getCell(0).getCellStyle().getFillForegroundColor()) + .isEqualTo(IndexedColors.DARK_BLUE.getIndex()); + assertThinBorders(workbook.getSheetAt(0).getRow(1).getCell(1).getCellStyle()); } } @@ -67,9 +73,21 @@ class ExcelReportServiceTest { assertThat(workbook.getSheetName(0)).isEqualTo("人员明细"); assertThat(workbook.getSheetAt(0).getRow(1).getCell(1).getStringCellValue()).isEqualTo("张三"); assertThat(workbook.getSheetAt(0).getRow(2).getCell(1).getStringCellValue()).isEqualTo("李四"); + assertThat(workbook.getSheetAt(0).getRow(1).getCell(1).getCellStyle().getFillPattern()) + .isEqualTo(FillPatternType.NO_FILL); + assertThat(workbook.getSheetAt(0).getRow(2).getCell(1).getCellStyle().getFillPattern()) + .isEqualTo(FillPatternType.NO_FILL); + assertThinBorders(workbook.getSheetAt(0).getRow(2).getCell(4).getCellStyle()); } } + private void assertThinBorders(org.apache.poi.ss.usermodel.CellStyle style) { + assertThat(style.getBorderTop()).isEqualTo(BorderStyle.THIN); + assertThat(style.getBorderBottom()).isEqualTo(BorderStyle.THIN); + assertThat(style.getBorderLeft()).isEqualTo(BorderStyle.THIN); + assertThat(style.getBorderRight()).isEqualTo(BorderStyle.THIN); + } + private Map baseEcReport() { Map report = new LinkedHashMap<>(); report.put("reportWindow", Map.of("startDate", "2026-07-01", "endDate", "2026-07-28"));