需求:實現下載模板功能,提供一個批次匯入的模板供下載使用。
思路:
1.使用者點選下載按鈕,向controller傳送請求
2.後端接受到請求,獲取到Excel模板檔案
3.將此檔案返回給前端頁面,供使用者下載
重點難點:
獲取到Excel檔案,返回到瀏覽器端。瀏覽端獲取到流以後怎麼返回給使用者下載。
解決思路:
Excel儲存在專案目錄下,用ClassPathResource載入Excel資原始檔,在透過輸入流讀取,在返回給響應的輸出流。
設定axios的responseType為blob
前端將接收的流轉化為blob物件,在供使用者下載。
遇到問題:
無法彈出下載框:ajax,axios 請求,返回來的是二進位制流的形式,所以是無法直接出現下載框的。
解決辦法:
1.直接 <a href=”> 請求 或者 表單請求。
2.轉換成blog物件在下載
核心程式碼:
程式碼:
前端js請求:
downLoadTemplate(){
downLoadExcelTemplate().then( res => {
//自定義檔名
let fileName="批次匯入Excel模板.xlsx"
//建立一個blob物件,將後端返回的內容存到blob物件裡
let blob = new Blob([res])
//建立一個dom元素
let downloadElement = document.createElement('a')
//createObjectURL方法生成一個對應Blob物件的URL,用於下載
let href = window.URL.createObjectURL(blob);
downloadElement.href = href;
//下載後檔名
downloadElement.download = fileName;
document.body.appendChild(downloadElement);
//執行點選下載
downloadElement.click();
//下載完成移除元素
document.body.removeChild(downloadElement);
//釋放blob物件
window.URL.revokeObjectURL(href);
})
}
後端:
@Override
public void downLoadExcelTemplate(HttpServletRequest request,HttpServletResponse response) {
String templatePath="template/ExcelTemplates.xlsx";
try {
ClassPathResource resource = new ClassPathResource(templatePath);
//清空快取
response.reset();
//返回的是二進位制流資料
response.setContentType("application/octet-stream;charset=utf-8");
//輸入流讀取
BufferedInputStream inputStream = new BufferedInputStream((resource.getInputStream()));
//getOutputStream() 可以向瀏覽器輸出響應資料
ServletOutputStream out = response.getOutputStream();
int b = 0;
byte[] buffer = new byte[1024];
while ((b = inputStream.read(buffer)) != -1) {
out.write(buffer, 0, b);
}
inputStream.close();
if (out != null) {
out.flush();
out.close();
}
} catch (IOException e) {
e.printStackTrace();
throw new BadRequestException("Excel模板下載異常");
}
}
參考:
(13條訊息) Vue axios 後端返回excel檔案流該如何下載_滑過了流星的部落格-CSDN部落格
SpringBoot之下載excel模板 - osc_uwnmtz9n的個人空間 - OSCHINA - 中文開源技術交流社群
詳解,從後端匯出檔案到前端(Blob)下載過程 - SegmentFault 思否
javascript - What is the difference between an ArrayBuffer and a Blob? - Stack Overflow
Servlet第三篇【request和response簡介、response的常見應用】 - SegmentFault 思否
HTTP content-type | 菜鳥教程 (runoob.com)
本作品採用《CC 協議》,轉載必須註明作者和本文連結