package com.vincent.rsf.server.common.utils; import org.apache.poi.ss.usermodel.CellStyle; import org.apache.poi.ss.usermodel.Font; import org.apache.poi.ss.usermodel.HorizontalAlignment; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; import org.junit.jupiter.api.Test; import java.lang.reflect.Constructor; import java.lang.reflect.Modifier; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.fail; class ExcelUtilReportStyleTest { @Test void exportMetaExposesPublicSixArgReportStyleConstructorContract() { Constructor constructor = findPublicReportStyleConstructor( "ExcelUtil.ExportMeta has not exposed a public reportStyle constructor contract yet; expected a public 6-arg constructor whose sixth parameter is a Map-compatible reportStyle payload." ); assertEquals(6, constructor.getParameterCount(), "ExcelUtil.ExportMeta must expose a public 6-arg constructor for reportStyle."); assertTrue( Map.class.isAssignableFrom(constructor.getParameterTypes()[5]), "ExcelUtil.ExportMeta public reportStyle constructor must accept a Map-compatible sixth argument." ); } @Test void createBuildsSharedReportSkeletonWhenLandscapeReportStyleIsProvided() throws Exception { Constructor constructor = findPublicReportStyleConstructor( "Cannot verify landscape reportStyle runtime behavior until ExcelUtil.ExportMeta exposes a public 6-arg constructor whose sixth parameter is a Map-compatible reportStyle payload." ); List> rows = List.of(row("1", "管理员")); List columns = List.of( new ExcelUtil.ExportColumn("sequence", "序号"), new ExcelUtil.ExportColumn("name", "角色名称") ); ExcelUtil.ExportMeta exportMeta = (ExcelUtil.ExportMeta) constructor.newInstance( "角色管理报表", "2026-03-29", "2026-03-29 10:00:00", "tester", rows.size(), Map.of( "orientation", "landscape", "showSequence", true ) ); try (Workbook workbook = ExcelUtil.create(rows, columns, exportMeta)) { Sheet sheet = workbook.getSheetAt(0); assertEquals("角色管理报表", sheet.getRow(0).getCell(0).getStringCellValue()); CellStyle titleStyle = sheet.getRow(0).getCell(0).getCellStyle(); assertEquals(HorizontalAlignment.CENTER, titleStyle.getAlignment()); Font titleFont = workbook.getFontAt(titleStyle.getFontIndex()); assertTrue(titleFont.getFontHeightInPoints() >= 14); assertTrue(sheet.getRow(1).getCell(0).getStringCellValue().startsWith("报表日期:")); assertTrue(sheet.getPrintSetup().getLandscape()); assertEquals("角色名称", sheet.getRow(3).getCell(1).getStringCellValue()); } } @Test void createPrependsSequenceColumnByDefaultWhenReportStyleOmitsShowSequence() throws Exception { Constructor constructor = findPublicReportStyleConstructor( "Cannot verify default showSequence behavior until ExcelUtil.ExportMeta exposes a public 6-arg constructor whose sixth parameter is a Map-compatible reportStyle payload." ); List> rows = List.of(row(null, "管理员")); List columns = List.of( new ExcelUtil.ExportColumn("name", "角色名称") ); ExcelUtil.ExportMeta exportMeta = (ExcelUtil.ExportMeta) constructor.newInstance( "角色管理报表", "2026-03-29", "2026-03-29 10:00:00", "tester", rows.size(), Map.of("orientation", "portrait") ); try (Workbook workbook = ExcelUtil.create(rows, columns, exportMeta)) { Sheet sheet = workbook.getSheetAt(0); assertEquals("序号", sheet.getRow(3).getCell(0).getStringCellValue()); assertEquals("1", sheet.getRow(4).getCell(0).getStringCellValue()); assertEquals("角色名称", sheet.getRow(3).getCell(1).getStringCellValue()); } } private Constructor findPublicReportStyleConstructor(String missingConstructorMessage) { for (Constructor constructor : ExcelUtil.ExportMeta.class.getConstructors()) { if (!Modifier.isPublic(constructor.getModifiers()) || constructor.getParameterCount() != 6) { continue; } Class[] parameterTypes = constructor.getParameterTypes(); if (Map.class.isAssignableFrom(parameterTypes[5])) { return constructor; } } fail(missingConstructorMessage); return null; } private Map row(String sequence, String name) { Map row = new LinkedHashMap<>(); row.put("sequence", sequence); row.put("name", name); return row; } }