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)化下載速度(可以研究一下分片下載,這里不做展開)
改造前端用戶體驗(比如點擊下載后你要顯示出來進度,讓客戶知道已經(jīng)在下載中了)
3. 具體實現(xiàn)
這里選擇了2.2中的方案,改造前端用戶體驗,寫這篇文章的目的是記錄當時的解決過程,希望能幫到大家;本文使用的方案技術(shù)背景:前端 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 這個對象要提前導(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)在計算了 這里要超過先前的計算才能繼續(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("點擊關(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==客戶手動取消下載');
}).catch(() => {
//取消--什么都不做
});
},
3.2 后臺代碼
后臺主要是要返回計算好的文件大小,否則上面前端計算進度的時候取的total永遠是0,這個就是一個隱藏的坑。
關(guān)鍵代碼:(下載完整后臺網(wǎng)上其實有很多,這里只是列出關(guān)鍵的和需要注意的點)
//獲取本地文件 并計算大小
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屬性設(shè)進去,否則也不生效
OutputStream out = response.getOutputStream();
后續(xù)省略.....
4. 總結(jié)
可能大家在使用過程中還會遇到一個問題,就是后端計算文件大小的時候花很多時間,導(dǎo)致前端也是半天進度條不動,用戶還是會覺得卡了,這樣就達不到我們的訴求了;
這里我這邊的解決方案是,前端做一個定時器,點擊下載的時候,定時器先跑,比如2秒增加1%的進度,等到后臺返回文件總大小的時候,計算出來的百分比(percentage)超過定時器走的百分比(percentage)的時候就關(guān)掉定時器,并替換那個進度百分比的屬性(percentage);記住一點,這個定時器自動加百分比(percentage)一定要設(shè)一個上限。
好處是用戶一點下載按鈕,前端就給出反應(yīng),雖然前面的反應(yīng)可能是假的,但是只要銜接好了,真假就無所謂了
到此這篇關(guān)于vue+element+springboot實現(xiàn)文件下載進度條展現(xiàn)功能示例的文章就介紹到這了,更多相關(guān)element springboot 下載進度條 內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Vue源碼學(xué)習(xí)之數(shù)據(jù)初始化
這篇文章主要為大家介紹了Vue源碼學(xué)習(xí)之數(shù)據(jù)初始化實例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-09-09
Vue + Vue-router 同名路由切換數(shù)據(jù)不更新的方法
本篇文章主要介紹了Vue + Vue-router 同名路由切換數(shù)據(jù)不更新的方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-11-11
關(guān)于eslint和prettier格式化沖突問題
這篇文章主要介紹了eslint和prettier格式化沖突問題,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-08-08

