最近在做一个关于性能测试管理系统,一个新的需求,需要导出测试报告,直接使用了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