在开发一个动态导出Excel的功能时,由于原功能使用了EasyPoi,所以直接在这个基础上修改,导出图片时遇到NullPointerException,原代码如下:
List<ExcelExportEntity> exportFields = new ArrayList<>();
//省略
ExcelExportEntity excelExportEntity = new ExcelExportEntity(key, value); //key为表格字段名,value为类的属性名
excelExportEntity.setType(2); //2代表图片
excelExportEntity.setExportImageType(2); //2代表值类型为byte[]
exportFields.add(excelExportEntity);
//省略
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, exportFields, temp);
由于业务要求,图片不能使用url地址,于是取了图片的字节流。
网上找了一圈,甚至连用同样方法的例子都没有,于是乎只能自己慢慢检查。
一步步进入方法,最后出问题的地方在这里:
public void createImageCell(Drawing patriarch, ExcelExportEntity entity, Row row, int i,
String imagePath, Object obj) throws Exception {
Cell cell = row.createCell(i);
byte[] value = null;
if (entity.getExportImageType() != 1) {
value = (byte[])((byte[])(entity.getMethods() != null ?
this.getFieldBySomeMethod(entity.getMethods(), obj) :
entity.getMethod().invoke(obj)));
}
this.createImageCell(cell, 50.0 * entity.getHeight(), entity.getExportImageType() == 1
? imagePath : null, value);
}
可以看到,如果选择的是字节流导出,则会使用entity的getMethod()反射获取obj中的属性值,此处的obj就是excel的行内容,由于entity的method为null,导致报错。
这里就有个坑,明明在构建ExcelExportEntity时指定了属性名,但是EasyPoi不会自动通过这个方法设置method(当然,由于没有指定类,它也没办法获取),所以在构建时,需要手动设置method为图片属性的get方法。
修改后如下:
excelExportEntity.setMethod(ExportExcel.class.getMethod("getImgByte"));
excelExportEntity.setType(2);
excelExportEntity.setExportImageType(2);