EasyExcel模板填充踩坑
参考EasyExcel中的复杂填充. 以下为官方示例代码:
/**
* 复杂的填充
*
* @since 2.1.1
*/
@Test
public void complexFill() {
// 模板注意 用{} 来表示你要用的变量 如果本来就有"{","}" 特殊字符 用"\{","\}"代替
// {} 代表普通变量 {.} 代表是list的变量
String templateFileName =
TestFileUtil.getPath() + "demo" + File.separator + "fill" + File.separator + "complex.xlsx";
String fileName = TestFileUtil.getPath() + "complexFill" + System.currentTimeMillis() + ".xlsx";
ExcelWriter excelWriter = EasyExcel.write(fileName).withTemplate(templateFileName).build();
WriteSheet writeSheet = EasyExcel.writerSheet().build();
// 这里注意 入参用了forceNewRow 代表在写入list的时候不管list下面有没有空行 都会创建一行,然后下面的数据往后移动。默认 是false,会直接使用下一行,如果没有则创建。
// forceNewRow 如果设置了true,有个缺点 就是他会把所有的数据都放到内存了,所以慎用
// 简单的说 如果你的模板有list,且list不是最后一行,下面还有数据需要填充 就必须设置 forceNewRow=true 但是这个就会把所有数据放到内存 会很耗内存
// 如果数据量大 list不是最后一行 参照下一个
FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build();
excelWriter.fill(data(), fillConfig, writeSheet);
excelWriter.fill(data(), fillConfig, writeSheet);
Map<String, Object> map = new HashMap<String, Object>();
map.put("date", "2019年10月9日13:28:28");
map.put("total", 1000);
excelWriter.fill(map, writeSheet);
excelWriter.finish();
}
模板中需要填充Header和List, header为表头, List为数据行.以下为Excel模板:
以下为填充数据的Class
@Data
public class RadioactivityVO {
/** 时间 */
private String date;
/** α值 */
private String aValue;
/** β值 */
private String bValue;
/** γ值 */
private String yValue;
}
我的代码
Map<String, String> header = new HashMap<>(4);
List<RadioactivityVO> data = new ArrayList<>();
// 这里代码在准备需要填充的数据 list 和 header, 这里不做展示了
// 模板读取
String tempFileName = "环境风险放射性数据导出表_" + System.currentTimeMillis() + ".xlsx";
String exportName = "环境风险放射性数据导出表.xlsx";
try {
ClassPathResource classPathResource = new ClassPathResource("templates/radioactivity_template.xlsx");
ExcelWriter excelWriter = EasyExcel.write(tempFileName)
.withTemplate(classPathResource.getInputStream())
.build();
WriteSheet writeSheet = EasyExcel.writerSheet().build();
excelWriter.fill(data, writeSheet);
excelWriter.fill(header, writeSheet);
excelWriter.finish();
return FileUtil.buildResponse(new File(tempFileName), exportName); // 返回一个ResponseEntity<byte[]>
} catch (Exception e) {
log.error("", e);
throw new RuntimeException("环境风险放射性数据导出异常");
}
遇到的问题,如图所示, 只有表头与时间列有数据, 其他列为空白.
解决步骤:
- 查看列表数据中其他字段(aValue, bValue, cValue) 是否有值?
debug结果: 有值. (部分字段为null 可以忽略, 这是业务本身的问题)
- 检查Excel模板中 列字段设置与Java中的属性是否相对应, 检查结果为对应.
- 另外一个模块也做了一个模板类似的导出功能, 并且导出后Excel数据正确显示. 其定义的模板与Java类如下:
@Data
public class RiskWaterExportVO {
/** 时间 */
private String date;
/** 温度 */
private String temperature;
/** 电导率 */
private String conductivity;
/** 铅 */
private String pb;
/** 镉 */
private String cd;
/** 锌 */
private String zd;
/** 铜 */
private String cu;
}
对比两个模板的不同发现:
能正确显示的模板中 列表数据数据的字段全都为小写, 而未填充数据的模板中列表里面属性有大写, 比如aValue, bValue, yValue.
解决思路
将模板与Java类中大写后面的Value去掉. 如图:
@Data
public class RadioactivityVO {
/** 时间 */
private String date;
/** α值 */
private String a;
/** β值 */
private String b;
/** γ值 */
private String y;
}
再次导出数据显示正确, 结果如图:
结论
官方说明的是
// {} 代表普通变量, {.} 代表是list的变量
盲猜EasyExcel复杂填充, 普通变量属性支持驼峰命名, 列表数据中的字段不支持驼峰命名????????