最近在做一個關於性能測試管理系統,一個新的需求,需要導出測試報告,直接使用了ali的封裝的EasyExcel,但是在復雜頭與一些樣式,就缺少了自定義的靈活性,在官方demo中沒有找到很好的解決方法。
不普及基礎了,可以直接看官方文檔, 直接上解決代碼:
調用:
List<ApiStatusVO> apiStatusVOList = new ArrayList<>(); for(int i=0;i<=15;i++){ ApiStatusVO apiStatusVO = new ApiStatusVO(); apiStatusVO.setApiName("Apiname"+i); apiStatusVO.setApiRt("RT"+i); apiStatusVO.setApiStatus("200"); apiStatusVO.setId(i); apiStatusVO.setTransId(String.valueOf(100+i)); apiStatusVO.setResponseAssert("true"); apiStatusVOList.add(apiStatusVO); }
String fileName = URLEncoder.encode(new SimpleDateFormat("yyyy-MM-dd-24h").format(new Date())+".xlsx", "UTF-8");
ExcelKit().parseExcelAndSave(apiStatusVOList,fileName );
ExcelKit代碼:
package com.kit; import ……public class ExcelKit { public static void parseExcelAndSave(List<ApiStatusVO> apiStatusVOS,String fileName){ EasyExcel.write(fileName, TestReportVO.class) .head(head("我是一個標題頭","描述:本次壓測針對UXX常用接口進行壓力測試;")) .registerWriteHandler(new CustomCellWriteHandler()) .sheet("TestReport") .doWrite(data(apiStatusVOS)); } /** * Api 返回內容 數據不全,先自定義賦值 * @param statusVOS * @return */ private static List<TestReportVO> data(List<ApiStatusVO> statusVOS){ List<TestReportVO> dataList = new ArrayList<>(); statusVOS.forEach(ApiStatusVO->{ TestReportVO status = new TestReportVO(); // @ExcelProperty("壓測接口名稱") status.setTestName(ApiStatusVO.getApiName()); // @ExcelProperty("壓測時間") status.setTestDate(new Date()); // @ExcelProperty("壓測時常(s)") status.setTestDuration("100"); // @ExcelProperty("平均吞吐量(s)") status.setTestHandlingCapacity("101"); // @ExcelProperty("平均響應時間(s)") status.setTestResponseTime(ApiStatusVO.getApiRt()); // @ExcelProperty("最大響應時間(s)") status.setTestMaxResponseTime("102"); // @ExcelProperty("錯誤率(%)") status.setTestErrorRate("13.18"); // @ExcelProperty("數據庫CPU(User)(%)") status.setTestCpuPercentum("15.18"); // @ExcelProperty("數據庫TCP連接數") status.setTestTcpLinkNum("105"); // @ExcelProperty("連接池大小") status.setTestLinkPooSize("106"); // @ExcelProperty("網絡流量(上傳/Mbps)(Min)") status.setTestMinFlow("107"); // @ExcelProperty("網絡流量(上傳/Mbps)(Max)") status.setTestMaxFlow("108"); dataList.add(status); }); return dataList; } /** * 自定義頭 * @param headTitle 統一頭 * @param headDescTitle 描述頭 * @return 返回整個頭list。 頭部相同連續的單元格會自動合並。 */ private static List<List<String>> head(String headTitle, String headDescTitle){ List<List<String>> list = new ArrayList<List<String>>(); // 壓測名稱 壓測時間 壓測時常(s)平均吞吐量(s) 平均響應時間(s) 最大響應時間(s) 錯誤率(%) 數據庫CPU(User)(%) 數據庫TCP連接數 連接池大小 網絡流量(上傳/Mbps) 網絡流量(下載/Mbps) List<String> head1 = new ArrayList<String>(); head1.add(headTitle); head1.add(headDescTitle); head1.add(headDescTitle); head1.add(headDescTitle); head1.add(headDescTitle); head1.add(headDescTitle); head1.add(headDescTitle); head1.add("壓測名稱"); List<String> head2 = new ArrayList<String>(); head2.add(headTitle); head2.add(headDescTitle); head2.add(headDescTitle); head2.add(headDescTitle); head2.add(headDescTitle); head2.add(headDescTitle); head2.add(headDescTitle); head2.add("壓測時間"); List<String> head3 = new ArrayList<String>(); head3.add(headTitle); head3.add(headDescTitle); head3.add(headDescTitle); head3.add(headDescTitle); head3.add(headDescTitle); head3.add(headDescTitle); head3.add(headDescTitle); head3.add("壓測時常(s)"); List<String> head4 = new ArrayList<String>(); head4.add(headTitle); head4.add(headDescTitle); head4.add(headDescTitle); head4.add(headDescTitle); head4.add(headDescTitle); head4.add(headDescTitle); head4.add(headDescTitle); head4.add("平均吞吐量(s)"); List<String> head5 = new ArrayList<String>(); head5.add(headTitle); head5.add(headDescTitle); head5.add(headDescTitle); head5.add(headDescTitle); head5.add(headDescTitle); head5.add(headDescTitle); head5.add(headDescTitle); head5.add("平均響應時間(s)"); List<String> head6 = new ArrayList<String>(); head6.add(headTitle); head6.add(headDescTitle); head6.add(headDescTitle); head6.add(headDescTitle); head6.add(headDescTitle); head6.add(headDescTitle); head6.add(headDescTitle); head6.add("最大響應時間(s)"); List<String> head7 = new ArrayList<String>(); head7.add(headTitle); head7.add(headDescTitle); head7.add(headDescTitle); head7.add(headDescTitle); head7.add(headDescTitle); head7.add(headDescTitle); head7.add(headDescTitle); head7.add("錯誤率(%)"); List<String> head8 = new ArrayList<String>(); head8.add(headTitle); head8.add(headDescTitle); head8.add(headDescTitle); head8.add(headDescTitle); head8.add(headDescTitle); head8.add(headDescTitle); head8.add(headDescTitle); head8.add("數據庫CPU(User)(%)"); List<String> head9 = new ArrayList<String>(); head9.add(headTitle); head9.add(headDescTitle); head9.add(headDescTitle); head9.add(headDescTitle); head9.add(headDescTitle); head9.add(headDescTitle); head9.add(headDescTitle); head9.add("數據庫TCP連接數"); List<String> head10 = new ArrayList<String>(); head10.add(headTitle); head10.add("負責人:"); head10.add("齊冰洋"); head10.add(""); head10.add(""); head10.add(""); head10.add(""); head10.add("連接池大小"); List<String> head11 = new ArrayList<String>(); head11.add(headTitle); head11.add("協助人:"); head11.add("石星"); head11.add("張剛強"); head11.add("秦亞飛"); head11.add("王京朝"); head11.add("張凱"); head11.add("網絡流量(上傳/Mbps)"); List<String> head12 = new ArrayList<String>(); head12.add(headTitle); head12.add(""); head12.add("黃色:瓶頸"); head12.add("橙色:提醒"); head12.add("紅色:嚴重"); head12.add("測試時間"); head12.add("2020-01-01"); //測試時間 head12.add("網絡流量(下載/Mbps)"); list.add(head1); list.add(head2); list.add(head3); list.add(head4); list.add(head5); list.add(head6); list.add(head7); list.add(head8); list.add(head9); list.add(head10); list.add(head11); list.add(head12); return list; } }
攔截,寫入樣式、控制列寬:
package com.kit; import ……public class CustomCellWriteHandler extends AbstractCellStyleStrategy implements CellWriteHandler { private static final Integer width = 18; Workbook workbooks; @Override public void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Head head, Integer integer, Integer integer1, Boolean aBoolean) { } @Override public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, List<CellData> list, Cell cell, Head head, Integer integer, Boolean aBoolean) { } @Override public void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell, Head head, Integer integer, Boolean isHead) { this.initCellStyle(writeSheetHolder.getSheet().getWorkbook()); writeSheetHolder.getSheet().setColumnWidth(cell.getColumnIndex(), width * 256); this.setHeadCellStyle(cell,head,integer); } @Override protected void initCellStyle(Workbook workbook) { this.workbooks = workbook; } @Override protected void setHeadCellStyle(Cell cell, Head head, Integer integer) { //頭部Top樣式 if(cell.getRowIndex()==0){ cell.setCellStyle(PoiUtils.getColumnTopStyle(workbooks,16)); }else if((cell.getRowIndex()==1 && cell.getColumnIndex()>8)){ //負責人 、協助人 cell.setCellStyle(PoiUtils.getColumnTopStyle(workbooks,IndexedColors.GREEN)); }else if(cell.getColumnIndex() == 11 && (cell.getRowIndex() == 2 || cell.getRowIndex() == 3 || cell.getRowIndex() == 4 || cell.getRowIndex() == 5)){ //警告 switch (cell.getRowIndex()){ case 2: cell.setCellStyle(PoiUtils.getColumnTopStyle(workbooks,IndexedColors.YELLOW)); break; case 3: cell.setCellStyle(PoiUtils.getColumnTopStyle(workbooks,IndexedColors.ORANGE)); break; case 4: cell.setCellStyle(PoiUtils.getColumnTopStyle(workbooks,IndexedColors.RED)); break; case 5: cell.setCellStyle(PoiUtils.getColumnTopStyle(workbooks,IndexedColors.GREEN)); break; } }else if(cell.getRowIndex() == 7 && cell.getColumnIndex() == 0 ){ //標題底色 cell.setCellStyle(PoiUtils.getColumnTopStyle(workbooks,IndexedColors.GREEN)); }else if(cell.getRowIndex() == 7 && cell.getColumnIndex() != 0 ){ //標題底色 cell.setCellStyle(PoiUtils.getColumnTopStyle(workbooks,IndexedColors.ORANGE)); }else { cell.setCellStyle(PoiUtils.getColumnStyle(workbooks)); } if(cell.getRowIndex() > 7){ cell.setCellStyle(PoiUtils.getColumnStyle(workbooks)); } } @Override protected void setContentCellStyle(Cell cell, Head head, Integer integer) { } }
樣式設置: 此處代碼參考來源:https://blog.csdn.net/qq_15081901/article/details/90202723 (POI封裝工具easyexcel導出EXCEL表樣式設置)
package com.kit; import……public class PoiUtils { /** * 首頭單元格 * @param workbook * @return */ public static CellStyle getColumnTopStyle(Workbook workbook,int FontSize) { if(FontSize == 0){ FontSize=12; } // 設置字體 Font font = workbook.createFont(); //設置字體大小 font.setFontHeightInPoints((short) FontSize); //字體加粗 font.setBold(true); //設置字體名字 font.setFontName("宋體"); //設置樣式; CellStyle style = workbook.createCellStyle(); //設置底邊框; style.setBorderBottom(BorderStyle.THIN); //設置底邊框顏色; style.setBottomBorderColor((short) 0); //設置左邊框; style.setBorderLeft(BorderStyle.THIN); //設置左邊框顏色; style.setLeftBorderColor((short) 0); //設置右邊框; style.setBorderRight(BorderStyle.THIN); //設置右邊框顏色; style.setRightBorderColor((short) 0); //設置頂邊框; style.setBorderTop(BorderStyle.THIN); //設置頂邊框顏色; style.setTopBorderColor((short) 0); //在樣式用應用設置的字體; style.setFont(font); //設置自動換行; style.setWrapText(false); //設置水平對齊的樣式為居中對齊; style.setAlignment(HorizontalAlignment.CENTER); //設置垂直對齊的樣式為居中對齊; style.setVerticalAlignment(VerticalAlignment.CENTER); return style; } /** * 頭部自己定義單元格 * @param workbook * @return */ public static CellStyle getColumnTopStyle(Workbook workbook, IndexedColors indexedColors) { // 設置字體 Font font = workbook.createFont(); //設置字體大小 font.setFontHeightInPoints((short) 12); //字體加粗 font.setBold(true); //設置字體名字 font.setFontName("宋體"); //設置樣式; CellStyle style = workbook.createCellStyle(); //設置底邊框; style.setBorderBottom(BorderStyle.THIN); //設置底邊框顏色; style.setBottomBorderColor((short) 0); //設置左邊框; style.setBorderLeft(BorderStyle.THIN); //設置左邊框顏色; style.setLeftBorderColor((short) 0); //設置右邊框; style.setBorderRight(BorderStyle.THIN); //設置右邊框顏色; style.setRightBorderColor((short) 0); //設置頂邊框; style.setBorderTop(BorderStyle.THIN); //設置頂邊框顏色; style.setTopBorderColor((short) 0); //在樣式用應用設置的字體; style.setFont(font); //設置自動換行; style.setWrapText(false); //設置水平對齊的樣式為居中對齊; style.setAlignment(HorizontalAlignment.CENTER); //設置垂直對齊的樣式為居中對齊; style.setVerticalAlignment(VerticalAlignment.CENTER); /** * 背景色 */ if(indexedColors != null){ style.setFillForegroundColor(indexedColors.getIndex());// 設置背景色 style.setFillPattern(FillPatternType.SOLID_FOREGROUND); } return style; } /* * 字段樣式 */ public static CellStyle getColumnStyle(Workbook workbook) { // 設置字體 Font font = workbook.createFont(); //設置字體大小 font.setFontHeightInPoints((short) 10); //字體加粗 // font.setBold(true); //設置字體名字 font.setFontName("宋體"); //設置樣式; CellStyle style = workbook.createCellStyle(); //設置底邊框; style.setBorderBottom(BorderStyle.THIN); //設置底邊框顏色; style.setBottomBorderColor((short) 0); //設置左邊框; style.setBorderLeft(BorderStyle.THIN); //設置左邊框顏色; style.setLeftBorderColor((short) 0); //設置右邊框; style.setBorderRight(BorderStyle.THIN); //設置右邊框顏色; style.setRightBorderColor((short) 0); //設置頂邊框; style.setBorderTop(BorderStyle.THIN); //設置頂邊框顏色; style.setTopBorderColor((short) 0); //在樣式用應用設置的字體; style.setFont(font); //設置自動換行; style.setWrapText(true); //設置水平對齊的樣式為居中對齊; style.setAlignment(HorizontalAlignment.CENTER); //設置垂直對齊的樣式為居中對齊; style.setVerticalAlignment(VerticalAlignment.CENTER); return style; } }
TestReportVO
import …… @Data public class TestReportVO { @ExcelProperty("壓測名稱") private String testName; @ExcelProperty("壓測時間") private Date testDate; @ExcelProperty("壓測時常(s)") private String testDuration; @ExcelProperty("平均吞吐量(s)") private String testHandlingCapacity; @ExcelProperty("平均響應時間(s)") private String testResponseTime ; @ExcelProperty("最大響應時間(s)") private String testMaxResponseTime; @ExcelProperty(錯誤率(%)) private String testErrorRate ; @ExcelProperty("數據庫CPU(User)(%)) private String testCpuPercentum ; @ExcelProperty("數據庫TCP連接數") private String testTcpLinkNum; @ExcelProperty("連接池大小") private String testLinkPooSize; @ExcelProperty("網絡流量(上傳/Mbps)") private String testMinFlow ; @ExcelProperty("網絡流量(上傳/Mbps)") private String testMaxFlow; }
導出效果:
有問題可以聯系 郵箱 253049953@qq.com
TestReportVO