This article mainly introduces the example of vue+element+springboot to realize the file download progress bar display function, and shares it with you. The details are as follows Final Rendering 1. Demand BackgroundRecently, we received an optimization request. The original system file download function was not user-friendly, especially when downloading some time-consuming files. Users waited on the page without knowing the download progress and always thought the system was stuck. 2. Optimization plan Optimize download speed in the background (you can study fragmented downloading, but I won’t expand on it here) 3. Specific implementationHere we choose the solution in 2.2 to transform the front-end user experience. The purpose of writing this article is to record the solution process at that time, hoping to help everyone; the technical background of the solution used in this article: front-end vue + element-ui, back-end: springboot front-end and back-end separation, without further ado, directly on the code; 3.1 Front-end code1. Define a pop-up layer (the style can be determined according to your own preferences) <!--Download progress bar--> <el-dialog title="Downloading, please wait" :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">Cancel download</el-button> </div> </el-dialog> Define an object in data() fileDown: { loadDialogStatus: false, // Pop-up box control status percentage: 0, // Progress bar percentage source: {}, // Cancel download resource object }, 3. Main method (note to replace the following parameters, background address, file name, etc.) downFile(row) { //Put parameters here var param = {}; this.fileDown.loadDialogStatus = true; this.fileDown.percentage = 0; const instance = this.initInstance(); instance({ method: "post", withCredentials: true, url: "Replace download address", 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("Download failed"); return ; } const blob = new Blob([content]); const fileName = row.fileName; //Replace the file name if ("download" in document.createElement("a")) { // Non-IE download 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); // Release the URL object document.body.removeChild(elink); }, 100); } else { // IE10+ download navigator.msSaveBlob(blob, fileName); } }).catch(error => { this.fileDown.loadDialogStatus = false; console.info(error); }); }, initInstance() { var _this = this; //Resource token for cancellation this.fileDown.source = axios.CancelToken.source(); const instance = axios.create({ //The axios object should be imported in advance or replaced with your globally defined onDownloadProgress: function(ProgressEvent) { const load = ProgressEvent.loaded; const total = ProgressEvent.total; const progress = (load / total) * 100; console.log('progress='+progress); // Calculation has already been done at the beginning. This must exceed the previous calculation to continue if (progress > _this.fileDown.percentage) { _this.fileDown.percentage = Math.floor(progress); } if(progress == 100){ //Download completed_this.fileDown.loadDialogStatus = false; } }, cancelToken: this.fileDown.source.token, //Declare a cancel request token }); return instance; }, downClose() { //Interrupt download this.$confirm("Clicking Close will interrupt the download. Are you sure you want to close it?", this.$t("button.tip"), { confirmButtonText: this.$t("button.confirm"), cancelButtonText: this.$t("button.cancel"), type: "warning" }).then(() => { //Interrupt download callback this.fileDown.source.cancel('log==customer manually canceled download'); }).catch(() => { //Cancel -- do nothing}); }, 3.2 Background Code The main purpose of the background is to return the calculated file size, otherwise the total taken when the front-end calculates the progress will always be 0, which is a hidden pit. //Get the local file and calculate the sizeFile file = new File(zipFileName);//Read the compressed fileInputStream inputStream = new FileInputStream(file); int totalSize = inputStream.available(); //Get the file size logger.info("After compression === current file download size size={}", totalSize); response.setHeader("Content-Length", totalSize+""); //Note that you must set the setHeader property before response.getOutputStream(), otherwise it will not take effect OutputStream out = response.getOutputStream(); Subsequent omissions... 4. Conclusion You may encounter another problem during use, that is, the backend takes a lot of time to calculate the file size, causing the front-end progress bar to remain motionless for a long time, and users will still feel stuck, which does not meet our needs; My solution here is to make a timer on the front end. When you click download, the timer will run first, for example, increasing the progress by 1% in 2 seconds. When the total file size is returned by the background, when the calculated percentage (percentage) exceeds the percentage (percentage) of the timer, turn off the timer and replace the attribute (percentage) of the progress percentage. Remember, there must be an upper limit for the automatic percentage increase (percentage) of this timer. This is the end of this article about vue+element+springboot to implement a file download progress bar display function example. For more related element springboot download progress bar content, please search 123WORDPRESS.COM's previous articles or continue to browse the following related articles. I hope you will support 123WORDPRESS.COM in the future! You may also be interested in:
|
>>: Solve the problem that Docker pulls MySQL image too slowly
This article example shares the specific code of ...
There are many types of auto-increment IDs used i...
This article introduces the installation and use ...
I finished learning SQL by myself not long ago, a...
Install MySQL under Windows for your reference. T...
Basic Introduction to Floating In the standard do...
This article shares the specific code of JavaScri...
Table of contents 1. Concept 1.1 What are errors ...
1. Table structure TABLE person id name 1 you 2 Y...
In the database, both UNION and UNION ALL keyword...
1. Compatibility As shown below: The compatibilit...
Preface: When you execute a SQL statement in MySQ...
This article example shares the specific code of ...
It can be referenced through CDN (Content Delivery...
This article refers to the work of 51CTO blog aut...