首页 前端知识 vue下载文件时显示进度条

vue下载文件时显示进度条

2024-06-08 09:06:58 前端知识 前端哥 600 777 我要收藏

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

 

 

 

转载请注明出处或者链接地址:https://www.qianduange.cn//article/11475.html
标签
评论
发布的文章

echarts柱状图自动轮播

2024-06-16 01:06:46

Echarts--markPoint属性

2024-06-16 01:06:45

大家推荐的文章
会员中心 联系我 留言建议 回顶部
复制成功!