vue+element+springboot實(shí)現(xiàn)文件下載進(jìn)度條展現(xiàn)功能示例
本文主要介紹了vue+element+springboot實(shí)現(xiàn)文件下載進(jìn)度條展現(xiàn)功能示例,分享給大家,具體如下
最終效果圖
1. 需求背景
最近接到一個(gè)優(yōu)化需求,原系統(tǒng)文件下載功能體驗(yàn)不友好,特別是下載一些比較耗時(shí)的文件,用戶在頁(yè)面上傻等不知道下載的進(jìn)度是怎么樣的,總以為是系統(tǒng)卡死了。
2. 優(yōu)化方案
后臺(tái)優(yōu)化下載速度(可以研究一下分片下載,這里不做展開)
改造前端用戶體驗(yàn)(比如點(diǎn)擊下載后你要顯示出來(lái)進(jìn)度,讓客戶知道已經(jīng)在下載中了)
3. 具體實(shí)現(xiàn)
這里選擇了2.2中的方案,改造前端用戶體驗(yàn),寫這篇文章的目的是記錄當(dāng)時(shí)的解決過(guò)程,希望能幫到大家;本文使用的方案技術(shù)背景:前端 vue + element-ui,后臺(tái):springboot 前后端分離,廢話不多說(shuō),直接上代碼;
3.1 前端代碼
1.定義一個(gè)彈出層(樣式各位看官根據(jù)自己的喜好來(lái))
<!--下載進(jìn)度條--> <el-dialog title="正在下載,請(qǐng)等待" :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()中定義一個(gè)對(duì)象
fileDown: { loadDialogStatus: false, //彈出框控制的狀態(tài) percentage: 0, //進(jìn)度條的百分比 source: {}, //取消下載時(shí)的資源對(duì)象 },
3.主要方法(注意替換下面的參數(shù),后臺(tái)地址、文件名等)
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 對(duì)象 document.body.removeChild(elink); }, 100); } else { // IE10+下載 navigator.msSaveBlob(blob, fileName); } }).catch(error => { this.fileDown.loadDialogStatus = false; console.info(error); }); }, initInstance() { var _this = this; //取消時(shí)的資源標(biāo)記 this.fileDown.source = axios.CancelToken.source(); const instance = axios.create({ //axios 這個(gè)對(duì)象要提前導(dǎo)入 或者替換為你們?nèi)侄x的 onDownloadProgress: function(ProgressEvent) { const load = ProgressEvent.loaded; const total = ProgressEvent.total; const progress = (load / total) * 100; console.log('progress='+progress); //一開始已經(jīng)在計(jì)算了 這里要超過(guò)先前的計(jì)算才能繼續(xù)往下 if (progress > _this.fileDown.percentage) { _this.fileDown.percentage = Math.floor(progress); } if(progress == 100){ //下載完成 _this.fileDown.loadDialogStatus = false; } }, cancelToken: this.fileDown.source.token,//聲明一個(gè)取消請(qǐng)求token }); return instance; }, downClose() { //中斷下載 this.$confirm("點(diǎn)擊關(guān)閉后將中斷下載,是否確定關(guān)閉?", this.$t("button.tip"), { confirmButtonText: this.$t("button.confirm"), cancelButtonText: this.$t("button.cancel"), type: "warning" }).then(() => { //中斷下載回調(diào) this.fileDown.source.cancel('log==客戶手動(dòng)取消下載'); }).catch(() => { //取消--什么都不做 }); },
3.2 后臺(tái)代碼
后臺(tái)主要是要返回計(jì)算好的文件大小,否則上面前端計(jì)算進(jìn)度的時(shí)候取的total永遠(yuǎn)是0,這個(gè)就是一個(gè)隱藏的坑。
關(guān)鍵代碼:(下載完整后臺(tái)網(wǎng)上其實(shí)有很多,這里只是列出關(guān)鍵的和需要注意的點(diǎn))
//獲取本地文件 并計(jì)算大小 File file = new File(zipFileName);//讀取壓縮文件 InputStream inputStream = new FileInputStream(file); int totalSize = inputStream.available(); //獲取文件大小 logger.info("壓縮后===當(dāng)前文件下載大小size={}", totalSize); response.setHeader("Content-Length", totalSize+"");//這里注意 一定要在response.getOutputStream()之前就把這個(gè)setHeader屬性設(shè)進(jìn)去,否則也不生效 OutputStream out = response.getOutputStream(); 后續(xù)省略.....
4. 總結(jié)
可能大家在使用過(guò)程中還會(huì)遇到一個(gè)問(wèn)題,就是后端計(jì)算文件大小的時(shí)候花很多時(shí)間,導(dǎo)致前端也是半天進(jìn)度條不動(dòng),用戶還是會(huì)覺(jué)得卡了,這樣就達(dá)不到我們的訴求了;
這里我這邊的解決方案是,前端做一個(gè)定時(shí)器,點(diǎn)擊下載的時(shí)候,定時(shí)器先跑,比如2秒增加1%的進(jìn)度,等到后臺(tái)返回文件總大小的時(shí)候,計(jì)算出來(lái)的百分比(percentage)超過(guò)定時(shí)器走的百分比(percentage)的時(shí)候就關(guān)掉定時(shí)器,并替換那個(gè)進(jìn)度百分比的屬性(percentage);記住一點(diǎn),這個(gè)定時(shí)器自動(dòng)加百分比(percentage)一定要設(shè)一個(gè)上限。
好處是用戶一點(diǎn)下載按鈕,前端就給出反應(yīng),雖然前面的反應(yīng)可能是假的,但是只要銜接好了,真假就無(wú)所謂了
到此這篇關(guān)于vue+element+springboot實(shí)現(xiàn)文件下載進(jìn)度條展現(xiàn)功能示例的文章就介紹到這了,更多相關(guān)element springboot 下載進(jìn)度條 內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- SpringBoot+ruoyi框架文件上傳和下載的實(shí)現(xiàn)
- SpringBoot中的文件上傳和異常處理詳解
- SpringBoot實(shí)現(xiàn)文件上傳下載實(shí)時(shí)進(jìn)度條功能(附源碼)
- SpringBoot簡(jiǎn)單實(shí)現(xiàn)文件上傳
- SpringBoot實(shí)現(xiàn)文件下載功能的方式分享
- springboot中Excel文件下載踩坑大全
- springboot單文件下載和多文件壓縮zip下載的實(shí)現(xiàn)
- 在 Spring Boot 項(xiàng)目中實(shí)現(xiàn)文件下載功能
- Spring Boot中進(jìn)行 文件上傳和 文件下載功能實(shí)現(xiàn)
相關(guān)文章
Vue源碼學(xué)習(xí)之?dāng)?shù)據(jù)初始化
這篇文章主要為大家介紹了Vue源碼學(xué)習(xí)之?dāng)?shù)據(jù)初始化實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09Vue組件中的data必須是一個(gè)function的原因淺析
這篇文章主要介紹了Vue組件中的data必須是一個(gè)function的原因淺析,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-09-09Vue + Vue-router 同名路由切換數(shù)據(jù)不更新的方法
本篇文章主要介紹了Vue + Vue-router 同名路由切換數(shù)據(jù)不更新的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-11-11關(guān)于eslint和prettier格式化沖突問(wèn)題
這篇文章主要介紹了eslint和prettier格式化沖突問(wèn)題,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-08-08Vue常見報(bào)錯(cuò)整理大全(從此報(bào)錯(cuò)不害怕)
寫代碼的過(guò)程中一定會(huì)遇到報(bào)錯(cuò),遇到報(bào)錯(cuò)不要擔(dān)心,認(rèn)真分析就可以解決報(bào)錯(cuò),同時(shí)積累經(jīng)驗(yàn),早日成為大牛,這篇文章主要給大家介紹了關(guān)于Vue常見報(bào)錯(cuò)整理的相關(guān)資料,需要的朋友可以參考下2022-08-08vue實(shí)現(xiàn)滑塊拖拽校驗(yàn)功能的全過(guò)程
vue驗(yàn)證滑塊功能,在生活中很多地方都可以見到,使用起來(lái)非常方便,這篇文章主要給大家介紹了關(guān)于vue實(shí)現(xiàn)滑塊拖拽校驗(yàn)功能的相關(guān)資料,需要的朋友可以參考下2021-08-08VUE實(shí)現(xiàn)密碼驗(yàn)證與提示功能
這篇文章主要為大家詳細(xì)介紹了VUE實(shí)現(xiàn)密碼驗(yàn)證與提示功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-10-10