vue+element+springboot實現(xiàn)文件下載進度條展現(xiàn)功能示例
本文主要介紹了vue+element+springboot實現(xiàn)文件下載進度條展現(xiàn)功能示例,分享給大家,具體如下
最終效果圖
1. 需求背景
最近接到一個優(yōu)化需求,原系統(tǒng)文件下載功能體驗不友好,特別是下載一些比較耗時的文件,用戶在頁面上傻等不知道下載的進度是怎么樣的,總以為是系統(tǒng)卡死了。
2. 優(yōu)化方案
后臺優(yōu)化下載速度(可以研究一下分片下載,這里不做展開)
改造前端用戶體驗(比如點擊下載后你要顯示出來進度,讓客戶知道已經在下載中了)
3. 具體實現(xiàn)
這里選擇了2.2中的方案,改造前端用戶體驗,寫這篇文章的目的是記錄當時的解決過程,希望能幫到大家;本文使用的方案技術背景:前端 vue + element-ui,后臺:springboot 前后端分離,廢話不多說,直接上代碼;
3.1 前端代碼
1.定義一個彈出層(樣式各位看官根據(jù)自己的喜好來)
<!--下載進度條--> <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, //彈出框控制的狀態(tài) percentage: 0, //進度條的百分比 source: {}, //取消下載時的資源對象 },
3.主要方法(注意替換下面的參數(shù),后臺地址、文件名等)
downFile(row) { //這里放參數(shù) 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([content]); 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); //一開始已經在計算了 這里要超過先前的計算才能繼續(xù)往下 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"), 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(); 后續(xù)省略.....
4. 總結
可能大家在使用過程中還會遇到一個問題,就是后端計算文件大小的時候花很多時間,導致前端也是半天進度條不動,用戶還是會覺得卡了,這樣就達不到我們的訴求了;
這里我這邊的解決方案是,前端做一個定時器,點擊下載的時候,定時器先跑,比如2秒增加1%的進度,等到后臺返回文件總大小的時候,計算出來的百分比(percentage)超過定時器走的百分比(percentage)的時候就關掉定時器,并替換那個進度百分比的屬性(percentage);記住一點,這個定時器自動加百分比(percentage)一定要設一個上限。
好處是用戶一點下載按鈕,前端就給出反應,雖然前面的反應可能是假的,但是只要銜接好了,真假就無所謂了
到此這篇關于vue+element+springboot實現(xiàn)文件下載進度條展現(xiàn)功能示例的文章就介紹到這了,更多相關element springboot 下載進度條 內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Vue + Vue-router 同名路由切換數(shù)據(jù)不更新的方法
本篇文章主要介紹了Vue + Vue-router 同名路由切換數(shù)據(jù)不更新的方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-11-11