1. 程式人生 > 程式設計 >vue+element+springboot實現檔案下載進度條展現功能示例

vue+element+springboot實現檔案下載進度條展現功能示例

目錄
  • 1. 需求背景
  • 2. 優化方案
  • 3. 具體實現
    • 3.1 HlUbEIP前端程式碼
    • 3.2 後臺程式碼
  • 4. 總結

    本文主要介紹了+element+springboot實現檔案下載進度條展現功能示例,分享給大家,具體如下

    最終效果圖

    vue+element+springboot實現檔案下載進度條展現功能示例

    1. 需求背景

    最近接到一個優化需求,原系統檔案下載功能體驗不友好,特別是下載一些比較耗時的檔案,使用者在頁面上傻等不知道下載的進度是怎麼樣的,總以為是系統卡死了。

    2. 優化方案

    後臺優化下載速度(可以研究一下分片下載,這裡不做展開)
    改造前端使用者體驗(比如點選下載後你要顯示出來進度,讓客戶知道已經在下載中了)

    3. 具體實現

    這裡選擇了2.2中的方案,改造前端使用者體驗,寫這篇文章的目的是記錄當時的解決過程,希望能幫到大家;本文使用的方案技術背景:前端 vue + element-ui,後臺:springboot 前後端分離,廢話不多說,直接上程式碼;

    3.1 前端程式碼

    1.定義一個彈出層(樣式各位看官根據自己的喜好來)

    <!--下載進度條-->
        <el-dialog title="正在下載,請等待" :visible.sync="fileDown.loadDialogStatus" :close-on-click-modal="false" 
          :close-on-press-escape="false" :show-close="false" width="20%">
          <div style="text-align: center;">
            <el-progress type="circle" :percentage="fileDown.percentage"></el-progress>
          </div>
          <div slot="footer" class="dialog-footer">
            <el-button type="primary" @click="downClose">取消下載</el-button>
          </div>  
        </el-dialog>

    在data()中定義一個物件

    fileDown: {
            loadDialogStatus: false,//彈出框控制的狀態
            percentage: 0,//進度條的百分比
            source: {},//取消下載時的資源物件
          },

    3.主要方法(注意替換下面的引數,後臺地址、檔名等)

    downFile(row) {
        //這裡放參數
        var param = {};
        this.fileDown.loadDialogStatus = true;
        this.fileDown.percentage = 0;
        const instance = this.initInstance();
        instance({
            method: "post",withCredentials: true,url: "替換下載地址",params: param,responseType: "blob"
        }).then(res => {
            this.fileDown.loadDialogStatus = false;
            console.info(res);
            const content = res.data;
            if (content.size == 0) {
              this.loadClose();
              this.$alert("下載失敗");
              return ;
            }
            const blob = new Blob([chttp://www.cppcns.com
    ontent]www.cppcns.com); const fileName = row.fileName;//替換檔名 if ("download" in document.createElement("a")) { // 非IE下載 const elink = document.createElement("a"); elink.download = fileName; elink.style.display = "none"; elink.href = URL.createObjectURL(blob); document.body.appendChild(elink); elink.click(); setTimeout(function() { URL.revokeObjectURL(elink.href); // 釋放URL 物件 document.body.removeChild(elink); },100); } else { // IE10+下載 navigator.msSaveBlob(blob,fileName); } }).catch(error => { this.fileDown.loadDialogStatus = false; console.info(error); }); },initInstance() { var _this = this; //取消時的資源標記 this.fileDown.source = axios.CancelToken.source(); const instance = axios.create({ //axios 這個物件要提前匯入 或者替換為你們全域性定義的 onDownloadProgress: function(ProgressEvent) { const load = ProgressEvent.loaded; const total = ProgressEvent.total; const progress = (load / total) * 100; console.log('progress='+progress); //一開始已經在計算了 這裡要超過先前的計算才能繼續往下 if (progress > _this.fileDown.percentage) { _this.fileDown.percentage = Math.floor(progress); } if(progress == 100){ //下載完成 _this.fileDown.loadDialogStatus = false; } },cancelToken: this.fileDown.source.token,//宣告一個取消請求token }); return instance; },downClose() { //中斷下載 this.$confirm("點選關閉後將中斷下載,是否確定關閉?",this.$t("button.tip"),{ confirmButtonText: this.$t("button.confirm"),cancelButtonText: this.$t("button.cancel"),www.cppcns.com type: "warning" }).then(() => { //中斷下載回撥 this.fileDown.source.cancel('log==客戶手動取消下載'); }).catch(() => { //取消--什麼都不做 }); },

    3.2 後臺程式碼

    後臺主要是要返回計算好的檔案大小,否則上面前端計算進度的時候取的total永遠是0,這個就是一個隱藏的坑。
    關鍵程式碼:(下載完整後臺網上其實有很多,這裡只是列出關鍵的和需要注意的點)

    //獲取本地檔案 並計算大小
    File file = new File(zipFileName);//讀取壓縮檔案
    InputStream inputStream = new FileInputStream(file);
    int totalSize = inputStream.available(); //獲取檔案大小
    logger.info("壓縮後===當前檔案下載大小size={}",totalSize);
    response.setHeader("Content-Length",totalSize+"");//這裡注意 一定要在response.getOutputStream()之前就把這個setHeader屬性設進去,否則也不生效
    OutputStream out = response.getOutputStream();
    後續省略.....

    4. 總結

    可能大家在使用過程中還會遇到一個問題,就是後端計算檔案大小的時候花很多時間,導致前端也是半天進度條不動,使用者還是會覺得卡了,這樣就達不到我們的訴求了;

    這裡我這邊的解決方案是,前端做一個定時器,點選下載的時候,定時器先跑,比如2秒增加1%的進度,等到後臺返回檔案總大小的時候,計算出來的百分比(percentage)超過定時器走的百分比(percentage)的時候就關掉定時器,並替換那個進度百分比的屬性(percentage);記住一點,這個定時器自動加百分比(percentage)一定要設一個上限。
    好處是使用者一點下載按鈕,前端就給出反應,雖然前面的反應可能是假的,但是隻要銜接好了,真假就無所謂了

    到此這篇關於vue+element+springboot實現檔案下載進度條展現功能示例的文章就介紹到這了,更多相關element springboot 下載進度條 內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!