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没有进度条效果 所以出此下策 请辨别哦~~~~)