參考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復雜填充, 普通變量屬性支持駝峰命名, 列表數據中的字段不支持駝峰命名????????