Java使用EasyExcel生成動態(tài)表頭和多Sheet數據的Excel實例
Java使用EasyExcel生成動態(tài)表頭和多Sheet數據的Excel
由于業(yè)務需求,Excel的表頭需要固定表頭+動態(tài)表頭,不同Sheet使用不同的動態(tài)表頭進行Excel導出,這里還是使用EasyExcel進行數據導出,對關鍵部分代碼會進行釋義:
1、動態(tài)表頭+數據Excel
String fileName = "設備臺賬" + DateUtil.format(new Date(), DatePattern.PURE_DATE_FORMAT); //根據模版id進行分組,不同模板下的數據,導出為不同Sheet的數據 Map<Long, DeviceLedgerTemplateEntity> templateMap = deviceTemplateList.stream().collect(Collectors.toMap(DeviceLedgerTemplateEntity::getLedgerTemplateId, v -> v)); int i = 0; response.setContentType("application/vnd.ms-excel"); response.setCharacterEncoding("utf-8"); fileName = URLEncoder.encode(fileName, "UTF-8"); response.setHeader("Content-disposition", "attachment;filename=" + fileName + ";" + "filename*=utf-8''" + fileName + ".xlsx"); ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).build(); for (Map.Entry<Long, List<DeviceLedgerImportVO>> deviceMap : deviceTemplateMap.entrySet()) { Long templateId = deviceMap.getKey(); List<List<String>> headList = new ArrayList<>(); List<List<String>> dataList = new ArrayList<>(); if (templateMap.containsKey(templateId)) { DeviceLedgerTemplateEntity templateEntity = templateMap.get(templateId); List<FormDTO> formList = JSONArray.parseArray(templateEntity.getFormItems(), FormDTO.class); //動態(tài)生成多個Sheet的表頭 getHeadList(headList, formList); List<DeviceLedgerImportVO> deviceList = deviceTemplateMap.get(templateId); //動態(tài)填充多個Sheet的數據 getDataList(dataList, deviceList); //循環(huán)輸出sheet和表頭以及表格內容 WriteSheet sheet = EasyExcel.writerSheet(i, "Sheet" + (i + 1)).head(headList).build(); excelWriter.write(dataList, sheet); } i++; } excelWriter.finish();
- getHeadList 動態(tài)生成表頭
private void getHeadList(List<List<String>> headList, List<FormDTO> formList) { //生成Excel中表頭 //固定表頭 Field[] fields = DeviceLedgerImportVO.class.getDeclaredFields(); for (Field field : fields) { boolean bool = field.isAnnotationPresent(ExcelProperty.class); if (bool) { String value = Arrays.stream(field.getAnnotation(ExcelProperty.class).value()).findFirst().get(); List<String> filedList = new ArrayList<>(); filedList.add(value); headList.add(filedList); } } //動態(tài)表頭 formList.stream().forEach(form -> { List<String> filedList = new ArrayList<>(); filedList.add(form.getLabel()); headList.add(filedList); }); }
- getDataList 動態(tài)生出數據
private void getDataList(List<List<String>> dataList, List<DeviceLedgerImportVO> deviceList) { //生成Excel中值 deviceList.stream().forEach(device -> { //固定表頭下的數據 List<String> valueList = new ArrayList<>(); valueList.add(device.getDeviceSn()); valueList.add(device.getDeviceName()); valueList.add(device.getDeviceTypeName()); valueList.add(device.getLocation()); valueList.add(device.getStatus()); //動態(tài)表頭下的數據 List<FormDTO> formList = JSONArray.parseArray(device.getFormItems(), FormDTO.class); if (CollectionUtil.isNotEmpty(formList)) { formList.stream().forEach(form -> valueList.add(form.getValue())); } dataList.add(valueList); }); }
- Sheet1數據:
- Shee2數據:
也可以將Excel導出那部分寫到工具類,懶的抽出來了,也懶得寫Demo了,大概邏輯差不多,需要修改headList和dataList也根據索引導出每個Sheet的數據,在此,提供工具類:
注意:需要修改headList和dataList,不可直接使用上面的headList和dataList方法
public static void writeDynamicBatchExcel(HttpServletResponse response, String fileName, String sheetName, List<List<String>> headList, List<List<Object>> dataList) throws Exception { response.setContentType("application/vnd.ms-excel"); response.setCharacterEncoding("utf-8"); fileName = URLEncoder.encode(fileName, "UTF-8"); response.setHeader("Content-disposition", "attachment;filename=" + fileName + ";" + "filename*=utf-8''" + fileName + ".xlsx"); ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).build(); //循環(huán)輸出sheet和表頭以及表格內容 for (int i = 0; i < dataList.size(); i++) { WriteSheet sheet = EasyExcel.writerSheet(i, "Sheet" + (i + 1)).head(Collections.singletonList(headList.get(i))).build(); excelWriter.write(dataList.get(i), sheet); } excelWriter.finish(); }
2、動態(tài)表頭Excel
如果只生成動態(tài)表頭模版,不需要數據的話,getHeadList()不變,僅供參考
public void downloadDeviceLedger(DeviceLedgerSearchDTO param, HttpServletResponse response) throws IOException { //查詢模版 DeviceLedgerTemplateEntity templateEntity = deviceLedgerTemplateService.queryDeviceLedgerTemplate(param.getLedgerTemplateId()); List<FormDTO> formList = JSONArray.parseArray(templateEntity.getFormItems(), FormDTO.class); String fileName = "設備臺賬" + DateUtil.format(new Date(), DatePattern.PURE_DATE_FORMAT); List<List<String>> resultList = new ArrayList<>(); getHeadList(resultList, formList); EasyExcelUtils.writeDynamicExcel(response, fileName, "設備臺賬", resultList, Collections.EMPTY_LIST); }
EasyExcelUtils.writeDynamicExcel工具類:
public static void writeDynamicExcel(HttpServletResponse response, String fileName, String sheetName, List<List<String>> headList, List<List<Object>> dataList) throws IOException { response.setContentType("application/vnd.ms-excel"); response.setCharacterEncoding("utf-8"); fileName = URLEncoder.encode(fileName, "UTF-8"); response.setHeader("Content-disposition", "attachment;filename=" + fileName + ";" + "filename*=utf-8''" + fileName + ".xlsx"); EasyExcel.write(response.getOutputStream()) // 設置動態(tài)頭 .head(headList) .sheet(sheetName) .doWrite(dataList); }
總結
以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
解決HttpServletResponse和HttpServletRequest取值的2個坑
這篇文章主要介紹了解決HttpServletResponse和HttpServletRequest取值的2個坑問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-12-12Okhttp在SpringBoot中的應用實戰(zhàn)記錄(太強了)
這篇文章主要給大家介紹了關于Okhttp在SpringBoot中應用實戰(zhàn)的相關資料,在Spring Boot中使用OkHttp主要是為了發(fā)送HTTP請求和處理響應,OkHttp是一個高效、易用的HTTP客戶端庫,它具有簡潔的API和強大的功能,需要的朋友可以參考下2023-12-12