业务场景:我们使用poi实现数据导出时,通常是根据@Excel(name=“xxx”)来确定列名。通常情况下这个是不会发生变动的。但这里就说少数情况,在我们需要这里根据某些情况来进行改变的时候,我们就需要用到反射。
AirQualityRankingResp.java
@Data
public class AirQualityRankingResp {
/** 站点名称 */
@Excel(name = "站点名称")
private String site;
private String siteNumber;
@Excel(name = "分析时间")
private String dateTime;
/** 污染因子 */
private String pollutionFactor;
@Excel(name = "AQI")
private Double value;
/** 排名 */
@Excel(name = "排名")
private Integer ranking;
}
正常使用@Excel导出数据如下
动态修改@Excel的属性,代码实现
/**
* 通过反射动态设置导出的Excel列名
*
* @param annotatedColumnName:实体类中被@Excel注解的字段名
* @param annotationFieldName:实体类中被@Excel中注解的属性名
* @param newAnnotationFieldValue:属性的新值
*/
private void setExcelAnnotationValue(String annotatedColumnName, String annotationFieldName, String newAnnotationFieldValue){
try{
Class<AirQualityRankingResp> airQualityRankingRespClass = AirQualityRankingResp.class;
Field classDeclaredField = airQualityRankingRespClass.getDeclaredField(annotatedColumnName);
Excel excel = classDeclaredField.getAnnotation(Excel.class);
InvocationHandler excelInvocationHandler = Proxy.getInvocationHandler(excel);
Field excelInvocationHandlerField = excelInvocationHandler.getClass().getDeclaredField("memberValues");
excelInvocationHandlerField.setAccessible(true);
Map map = (Map) excelInvocationHandlerField.get(excelInvocationHandler);
map.put(annotationFieldName, newAnnotationFieldValue);
} catch (Exception e) {
e.printStackTrace();
}
}
@RequestMapping(value = "/rankingAnalysisExportXls")
public ModelAndView exportXls(HttpServletRequest request, AirRankingReq airRankingReq) {
switch (airRankingReq.getName()){
case "2":
setExcelAnnotationValue("value","name","SO2");
break;
case "3":
setExcelAnnotationValue("value","name","NO2");
break;
case "4":
setExcelAnnotationValue("value","name","PM10");
break;
case "5":
setExcelAnnotationValue("value","name","CO");
break;
case "6":
setExcelAnnotationValue("value","name","O3");
break;
case "7":
setExcelAnnotationValue("value","name","PM2.5");
break;
}
List<AirQualityRankingResp> list = lrMonitorConcentrationService.rankingAnalysis(airRankingReq);
// Step.3 AutoPoi 导出Excel
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
mv.addObject(NormalExcelConstants.FILE_NAME, "lr_meteorological_data"); //此处设置的filename无效 ,前端会重更新设置一下
mv.addObject(NormalExcelConstants.CLASS, AirQualityRankingResp.class);
//update-begin--Author:liusq Date:20210126 for:图片导出报错,ImageBasePath未设置--------------------
ExportParams exportParams = new ExportParams("空气质量数据排名" + "报表", "导出人:" + sysUser.getRealname(), "空气质量排名");
exportParams.setImageBasePath(upLoadPath);
//update-end--Author:liusq Date:20210126 for:图片导出报错,ImageBasePath未设置----------------------
mv.addObject(NormalExcelConstants.PARAMS, exportParams);
mv.addObject(NormalExcelConstants.DATA_LIST, list);
return mv;
}
我这里是根据前端给的name值来确定生成表格的列名为什么,你们根据实际业务场景来进行判断,这里知道怎么用即可