写在前面
老板说:系统很慢,下载半个小时无法下载,是否考虑先压缩再给用户下载?
本来是已经压缩过了,不过第一反应应该是用户下的数量多,导致压缩包很大,然后自己测试发现,只是等待的时间比较久而已,仍然是下载状态中,并不是系统慢,但是用户体验肯定是最直观的,确实是我们做得不够好,单纯弹出遮罩层显示冰冷的“拼命加载中……”,对用户来说确实不够友好。嗯,了解实际情况了,那就开撸,增加用户体验。
解决它
效果图:
Vue+ElementUI
<el-progress v-if="dlProgress>0" :text-inside="true" :stroke-width="18" :percentage="dlProgress" status="success" style="margin-bottom:10px"></el-progress>
Axios
downloadTask(index,row) {let own =this;this.fullscreenLoading = true;this.axios({method: 'post',url: this.baseUrl + '/api/Task/DownLoad',data: {id: row.id},responseType: 'blob', //敲黑板 onDownloadProgress (progress) {own.dlProgress=Math.round(progress.loaded / progress.total * 100);}}).then((res) => {this.fullscreenLoading = false;let fileName = decodeURI(res.headers["content-disposition"].split("=")[1]);let url = window.URL.createObjectURL(new Blob([res.data]));let link = document.createElement('a');link.style.display = 'none';link.href = url;link.setAttribute('download', fileName);document.body.appendChild(link);link.click(); document.body.removeChild(link); this.$message.success('下载成功');}).catch(() => {this.fullscreenLoading = false;});},
下载:
分片下载:
public static class HttpContextExtension{/// <summary>/// 通过文件流下载文件/// </summary>/// <param name="context"></param>/// <param name="filePath">文件完整路径</param>/// <param name="contentType">访问这里 https://tool.oschina.net/commons </param>public static void DownLoadFile(this HttpContext context,string filePath, string contentType= "application/octet-stream"){var fileName = Path.GetFileName(filePath);int bufferSize = 1024; context.Response.ContentType = contentType;context.Response.Headers.Append("Content-Disposition", "attachment;filename=" + HttpUtility.UrlEncode(fileName));context.Response.Headers.Append("Charset", "utf-8");context.Response.Headers.Append("Access-Control-Expose-Headers", "Content-Disposition");//context.Response.Headers.Append("Access-Control-Allow-Origin", "*");//使用FileStream开始循环读取要下载文件的内容using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read)){using (context.Response.Body) {long contentLength = fs.Length; context.Response.ContentLength = contentLength;byte[] buffer;long hasRead = 0; while (hasRead < contentLength){if (context.RequestAborted.IsCancellationRequested){break;}buffer = new byte[bufferSize];//从下载文件中读取bufferSize(1024字节)大小的内容到服务器内存中int currentRead = fs.Read(buffer, 0, bufferSize);context.Response.Body.Write(buffer, 0, currentRead);context.Response.Body.Flush();hasRead += currentRead;}context.Response.Body.Close();}fs.Close();}}/// <summary>/// 通过文件流下载文件/// </summary>/// <param name="context"></param>/// <param name="filePath">文件完整路径</param>/// <param name="contentType">访问这里 https://tool.oschina.net/commons </param>public static void DownLoadFile(this HttpContext context,string fileName, byte[] fileByte, string contentType = "application/octet-stream"){int bufferSize = 1024;context.Response.ContentType = contentType;context.Response.Headers.Append("Content-Disposition", "attachment;filename=" + HttpUtility.UrlEncode(fileName));context.Response.Headers.Append("Charset", "utf-8");context.Response.Headers.Append("Access-Control-Expose-Headers", "Content-Disposition");//context.Response.Headers.Append("Access-Control-Allow-Origin", "*");//使用FileStream开始循环读取要下载文件的内容using (Stream fs = new MemoryStream(fileByte)){using (context.Response.Body){long contentLength = fs.Length;context.Response.ContentLength = contentLength;byte[] buffer;long hasRead = 0;while (hasRead < contentLength){if (context.RequestAborted.IsCancellationRequested){break;}buffer = new byte[bufferSize];//从下载文件中读取bufferSize(1024字节)大小的内容到服务器内存中int currentRead = fs.Read(buffer, 0, bufferSize);context.Response.Body.Write(buffer, 0, currentRead);context.Response.Body.Flush();hasRead += currentRead;}}}}}
完美~