SpringBoot專案Excel下載功能

meimengxing發表於2022-10-27

需求:實現下載模板功能,提供一個批次匯入的模板供下載使用。
思路:

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 協議》,轉載必須註明作者和本文連結

相關文章