目的
根據業務需求對數據進行導出excel操作,該excel包括4個模版(sheet),每一個模板代表一個實體對象。如圖:
開始
本項目使用的是springboot + vue +elementUI 實現,由於需要使用導出excel功能,所以淺入了easyExcel模塊。
1、導入easyExcel坐標依賴
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>2.2.6</version>
</dependency>
easyExcel官方文檔:https://www.yuque.com/easyexcel/doc/quickstart
2、實體類編寫
在這里使用了lombok插件,使用easyExcel只需要設置導出的excel表列名,使用@ExcelProperty(value="")注解。具體配置列名、數據轉換,日期格式,自定義excel表格樣式,請去官網查看。
實體類部分圖
3、controller編寫
/**
* 導出檔案
*/
@RequestMapping("/export")
public void export(@RequestParam Map<String, Object> params, HttpServletResponse response) throws IOException {
OutputStream outputStream = response.getOutputStream();
// 獲取數據
PageUtils page = archService.getStatistics(params);
// 獲取農合檔案信息
List<ArchEntity> archEntityList = (List<ArchEntity>) page.getList();
// 遍歷設置List
if (archEntityList.size() > 0) {
List<FamilyEntity> familyEntityList = new ArrayList<>();
List<CardEntity> cardEntityList = new ArrayList<>();
List<PayEntity> payEntityList = new ArrayList<>();
for (int i = 0; i < archEntityList.size(); i++) {
// 獲取家庭檔案
familyEntityList.add(i, archEntityList.get(i).getFamilyEntity());
// 獲取慢性病卡檔案
cardEntityList.add(i, archEntityList.get(i).getCardEntity());
// 獲取慢性病報銷信息
payEntityList.add(i, archEntityList.get(i).getPayEntity());
}
try {
// 設置response
response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding("utf-8");
// 這里URLEncoder.encode可以防止中文亂碼 當然和easyexcel沒有關系
String fileName = URLEncoder.encode("統計信息", "UTF-8");
response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
//新建ExcelWriter
ExcelWriter excelWriter = EasyExcel.write(outputStream).build();
//獲取archSheet對象
WriteSheet archSheet = EasyExcel.writerSheet(0, "農合信息檔案").head(ArchEntity.class).build();
//獲取參合人員信息,向archSheet寫入數據
excelWriter.write(archEntityList, archSheet);
//獲取archSheet對象
WriteSheet familySheet = EasyExcel.writerSheet(1, "參合家庭檔案").head(FamilyEntity.class).build();
//獲取家庭參合信息,向familySheet寫入數據
excelWriter.write(familyEntityList, familySheet);
//獲取cardSheet對象
WriteSheet cardSheet = EasyExcel.writerSheet(2, "慢性病卡信息").head(CardEntity.class).build();
//獲取家庭參合信息,向cardSheett寫入數據
excelWriter.write(cardEntityList, cardSheet);
//獲取paySheet對象
WriteSheet paySheet = EasyExcel.writerSheet(3, "報銷記錄").head(PayEntity.class).build();
//獲取家庭參合信息,向paySheet寫入數據
excelWriter.write(payEntityList, paySheet);
//關閉流
excelWriter.finish();
outputStream.flush();
} catch (IOException e) {
log.error("導出異常{}", e.getMessage());
}
}
}
- 1、創建OutputStream對象
OutputStream outputStream = response.getOutputStream();
- 2、設置頭、類型、編碼格式
// 設置response
response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding("utf-8");
// 這里URLEncoder.encode可以防止中文亂碼 當然和easyexcel沒有關系
String fileName = URLEncoder.encode("統計信息", "UTF-8");
response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
- 3、創建ExcelWriter對象
//新建ExcelWriter
ExcelWriter excelWriter = EasyExcel.write(outputStream).build();
- 4、創建WriteSheet對象,調用EasyExcel.writerSheet()方法寫入參數
//獲取archSheet對象
WriteSheet archSheet = EasyExcel.writerSheet(0, "農合信息檔案").head(ArchEntity.class).build();
0為第一個模板(sheet),名稱是農合信息檔案。head()中傳入的參數為實體類
- 5、調用excelWriter.write()向sheet模板寫入參數
//獲取參合人員信息,向archSheet寫入數據
excelWriter.write(archEntityList, archSheet);
向excelWriter.write()方法中傳入List數據與WriteSheet對象
- 6、關閉excelWriter.finish()
//關閉流
excelWriter.finish();
- 7 、關閉outputStream.flush();
outputStream.flush();
3、前端界面編寫
// 導出檔案
exportHandle () {
this.$nextTick(() => {
this.$http({
url: this.$http.adornUrl('/mxbbx/arch/export'),
method: 'get',
responseType: 'blob',
params: this.$http.adornParams({
'page': this.pageIndex,
'limit': this.pageSize,
'groupId': this.dataForm.groupId,
'apName': this.dataForm.apName,
'areaTime': this.dataForm.areaTime,
'drName': this.dataForm.drName
})
}).then(({data}) => {
// 創建Blob對象
let blob = new Blob([data], { type: 'application/vnd.ms-excel;charset=utf-8' })
// 獲取路徑
let url = window.URL.createObjectURL(blob)
// 創建a標簽
const link = document.createElement('a')
// 設置a標簽鏈接參數
link.href = url
// 重命名文件
link.download = '報銷信息.xlsx'
link.click()
// 下載完成釋放URL 對象
URL.revokeObjectURL(url)
// 移除a標簽
document.body.removeChild(link)
})
})
},
注意事項
1、這里我使用的axios異步調用處理(和ajax沒啥大區別)
2、請求參數中設置:responseType: 'blob',將返回響應類型設置為blob
3、在返回成功then()中,創建a標簽,並為a標簽設置超鏈接,並設置點擊下載文件流。如果不使用創建a標簽的方式,將不會顯示下載彈窗!!!(大坑,后端成功了,前端一直沒有出現下載文件的彈窗,可能是vue的原因,在html中無需設置)
我的微信公眾號:Java架構師進階編程
專注分享Java技術干貨,期待你的關注!