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.data
data.forEach((x) => {
if (x.id === row.id) {
x.schedule = true
x.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.data
const blob = new Blob([content],{type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'})
if ('download' in document.createElement('a')) {
const elink = document.createElement('a')
elink.download = filename
elink.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'){
// IE
let blob = new Blob([content], {type: 'application/force-download'});
navigator.msSaveBlob(blob, filename)
}else {
// Firefox
var 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-body
width="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=true
this.selectionList.forEach(item=>{
this.exportReport(item)
})
});
})
.catch(() => {});
},
//关闭弹框清空选中状态
toClose(){
this.visible=false
this.onLoad(this.page);
this.$refs.crud.toggleSelection();
},
深拷贝方法(不使用深拷贝的话弹框和表格进度条会冲突!!!!!)
/**
* 对象深拷贝
*/
export const deepClone = data => {
var type = getObjType(data)
var obj
if (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没有进度条效果 所以出此下策 请辨别哦~~~~)