1.单个下载(开始是导出按钮 下载显示进度条)
html
<el-button @click.stop="exportReport(scope.row, scope.index)" v-if="!scope.row.schedule" icon="el-icon-download"size="small" type="text"style="color: #409eff">导出报告</el-button><el-progress style="width: 60px;display:inline-block;margin-left: 20px;" v-else :text-inside="true" :stroke-width="20" :percentage="scope.row.scheduleNumber" status="success" />
因为接口没有返回schedule和scheduleNumber数据只是前端需要 用来判断显示 按钮还是进度条的所以就手动给数组添加响应式数据
this.data.map((item, index) => {this.$set(item, 'schedule', false);this.$set(item, 'scheduleNumber', 0);return item;});
js部分
exportReport(row) {let data=this.visible?this.selectionList:this.data// 自己封装的方法downloadGet('/api/blade-robot/siteInfo/export-template','巡检报告', this.schedule, row).then(() => {data.forEach((x) => {if (x.id === row.id) {x.schedule = false}})})},schedule(progressEvent, row) {// 回调的progressEvent参数里有一个progressEvent.loaded和progressEvent.total两个参数,分别意思为已下载的文件大小和总文件大小// 因为total一直为0,经研究发现需要后端传给我ContentLength到response里这个值才会有值// 然而又发现后端使用的是minio这个文件服务器,所以这个文件大小太难获取了,所以我决定不改后端,直接写死了文件大小setTimeout(() => {let data=this.visible?this.selectionList:this.datadata.forEach((x) => {if (x.id === row.id) {x.schedule = truex.scheduleNumber = Math.round(progressEvent.loaded / 3715 * 100)if( x.schedule == true){setTimeout(() => {x.schedule = false}, 2000);}}})}, 2000);},
downloadGet方法
export const downloadGet = (url, filename, callback, callbackParameter)=> {return request({url:url, method: 'get',responseType: 'blob',timeout: 120000,// 下载的实时回调,axios里的onDownloadProgress: (a) => {if (callback) {callback(a, callbackParameter)}}}).then((r) => {// 下面的代码就是拿到字节流后转为文件的方法,想研究的可以自行百度const content = r.dataconst blob = new Blob([content],{type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'})if ('download' in document.createElement('a')) {const elink = document.createElement('a')elink.download = filenameelink.style.display = 'none'elink.href = URL.createObjectURL(blob)document.body.appendChild(elink)elink.click()URL.revokeObjectURL(elink.href)document.body.removeChild(elink)}else if (typeof window.navigator.msSaveBlob !== 'undefined'){// IElet blob = new Blob([content], {type: 'application/force-download'});navigator.msSaveBlob(blob, filename)}else {// Firefoxvar file = new File([content], filename, {type: 'application/force-download'});window.open(URL.createObjectURL(file));}}).catch((r) => {console.error(r)})
}
以上就可以实现每行下载时候去显示进度条了
2.批量下载弹框
弹框html
<el-dialog title="批量导出巡检报告" @close="toClose":close-on-click-modal="false" :visible="visible" lock-scroll append-to-bodywidth="600px" :modal-append-to-body="false"><el-table :data="selectionList" border style="width: 100%"><el-table-column type="index"label="序号" width="50"></el-table-column><el-table-column prop="id" label="文件名称"><template slot-scope="scope"><span>{{scope.row.id}}巡检报告</span></template></el-table-column><el-table-column prop="scheduleNumber" label="下载进度"><template slot-scope="scope"><el-progress :percentage="scope.row.scheduleNumber" :text-inside="true" :stroke- width="20" status="success"></el-progress></template></el-table-column></el-table>
</el-dialog>
js
import { deepClone } from "@/util/util";//引入深拷贝方法//表格选中多个selectionChange(list) {this.selectionList = deepClone(list);},//点击批量下载方法handleDelete() {if (this.selectionList.length === 0) {this.$message.warning("请选择至少一条数据");return;}this.$confirm("确定将选择数据批量导出巡检报告?", {confirmButtonText: "确定",cancelButtonText: "取消",type: "warning"}).then(() => {this.$nextTick(() => {this.visible=truethis.selectionList.forEach(item=>{this.exportReport(item)})});}).catch(() => {});},//关闭弹框清空选中状态toClose(){this.visible=falsethis.onLoad(this.page);this.$refs.crud.toggleSelection();},
深拷贝方法(不使用深拷贝的话弹框和表格进度条会冲突!!!!!)
/*** 对象深拷贝*/
export const deepClone = data => {var type = getObjType(data)var objif (type === 'array') {obj = []} else if (type === 'object') {obj = {}} else {//不再具有下一层次return data}if (type === 'array') {for (var i = 0, len = data.length; i < len; i++) {obj.push(deepClone(data[i]))}} else if (type === 'object') {for (var key in data) {obj[key] = deepClone(data[key])}}return obj
}
最后就是设置导出文件的类型在上文封装下载方法中 type设置的
const blob = new Blob([content],{type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'})
关于 Blob 的 content-type 的部分媒体类型 可以参照下面!!!!!
".*"="application/octet-stream"
".001"="application/x-001"
".301"="application/x-301"
".323"="text/h323"
".906"="application/x-906"
".907"="drawing/907"
".a11"="application/x-a11"
".acp"="audio/x-mei-aac"
".ai"="application/postscript"
".aif"="audio/aiff"
".aifc"="audio/aiff"
".aiff"="audio/aiff"
".anv"="application/x-anv"
".asa"="text/asa"
".asf"="video/x-ms-asf"
".asp"="text/asp"
".asx"="video/x-ms-asf"
".au"="audio/basic"
".avi"="video/avi"
".awf"="application/vnd.adobe.workflow"
".biz"="text/xml"
".bmp"="application/x-bmp"
".bot"="application/x-bot"
".c4t"="application/x-c4t"
".c90"="application/x-c90"
".cal"="application/x-cals"
".cat"="application/vnd.ms-pki.seccat"
".cdf"="application/x-netcdf"
".cdr"="application/x-cdr"
".cel"="application/x-cel"
".cer"="application/x-x509-ca-cert"
".cg4"="application/x-g4"
".cgm"="application/x-cgm"
".cit"="application/x-cit"".doc"="application/msword"
".docx"="application/vnd.openxmlformats-officedocument.wordprocessingml.document"
".rtf"="application/rtf"
".xls"="application/vnd.ms-excel application/x-excel"
".xlsx"="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
".ppt"="application/vnd.ms-powerpoint"
".pptx"="application/vnd.openxmlformats-officedocument.presentationml.presentation"
".pps"="application/vnd.ms-powerpoint"
".ppsx"="application/vnd.openxmlformats-officedocument.presentationml.slideshow"
".pdf"="application/pdf"
".swf"="application/x-shockwave-flash"
".dll"="application/x-msdownload"
".exe"="application/octet-stream"
".msi"="application/octet-stream"
".chm"="application/octet-stream"
".cab"="application/octet-stream"
".ocx"="application/octet-stream"
".rar"="application/octet-stream"
".tar"="application/x-tar"
".tgz"="application/x-compressed"
".zip"="application/x-zip-compressed"
".z"="application/x-compress"
".wav"="audio/wav"
".wma"="audio/x-ms-wma"
".wmv"="video/x-ms-wmv"
".mp3, .mp2, .mpe, .mpeg, .mpg"="audio/mpeg"
".rm"="application/vnd.rn-realmedia"
".mid, .midi, .rmi"="audio/mid"
".bmp"="image/bmp"
".gif"="image/gif"
".png"="image/png"
".tif, .tiff"="image/tiff"
".jpe, .jpeg, .jpg"="image/jpeg"
".txt"="text/plain"
".xml"="text/xml"
".html"="text/html"
".css"="text/css"
".js"="text/javascript"
".mht, .mhtml"="message/rfc822"
大概率就OK了!!!!!等待大文件联调看效果!!!!!!(其中的延时器是因为我现在测试的文件只有4kb没有进度条效果 所以出此下策 请辨别哦~~~~)