vue 实现文件上传、下载的方法

20,261 阅读1分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

下载

1. 第一种方式是前端创建超链接,通过a标签的链接向后端服务发get请求,接收后端的文件流

<a :href='"/user/downloadExcel"' >下载模板</a>

另一种情况是创建div标签,动态创建a标签:
<div name="downloadfile" onclick="downloadExcel()">下载</div>
function downloadExcel() {
    let a = document.createElement('a')
    a.href ="/user/downloadExcel"
    a.click();
} 
还有一种补充:
 function downloadExcel() {
    window.location.href = "/tUserHyRights/downloadUsersUrl";
} 

2. 通过创建iframe的方式

<el-button  size="mini" class="filter-item" type="primary" icon="el-icon-download" @click="handleExport(scope.row)">导出</el-button>
//method方法:
handleExport(row) {
      var elemIF = document.createElement('iframe')
      elemIF.src = 'user/downloadExcel?snapshotTime=' + formatDate(new Date(row.snapshotTime), 'yyyy-MM-dd hh:mm') +
                    '&category=' + row.category 
      elemIF.style.display = 'none'
      document.body.appendChild(elemIF)
    }

3. 向后端发的post请求,使用blob格式

var _this = this

      const _searchForm = this.$refs.searchForm.searchForm

      axios({ //该请求根据自己项目自己调整

        method: 'get',

        url: _this.baseUrl + 'prism/satisfaction/downloadTemplate',

        responseType: 'blob',

        params: { brand: 'xx', currentDate: _searchForm.currentDate, type: _searchForm.type, category: _searchForm.category },

        headers: {

          'data-type': 'Buffer',

          'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',

          'token': getToken()

        }

      }).then(res => {

        const url = window.URL.createObjectURL(new Blob([res.data]))

        const link = document.createElement('a')

        link.style.display = 'none'

        link.href = url

        link.setAttribute('download', 'all_sample_fa_kegg_blast_bst.xls') // 指定下载后的文件名,防跳转

        document.body.appendChild(link)

        link.click()

      })

上传

1. input方式

vue中的文件上传主要分为两步:前台获取到文件和提交到后台。

(1)前台获取文件,主要是采用input框来实现。

<input type="file" ref="clearFile" @change="getFile($event)" multiple="multiplt" class="add-file-right-input" style="margin-left:70px;" accept=".docx,.doc,.pdf">

<el-button type="primary" @click="submitAddFile" size="small">开始上传</el-button>

通过file类型的input框实现文件上传;然后通过设置multiple="multiplt"实现了多文件上传,并且使用accept实现了上传文件类型限制;最后通过监听change事件,前台获取到上传的文件。

getFile(event){
       var file = event.target.files;
       for(var i = 0;i<file.length;i++){
        //    上传类型判断
           var imgName = file[i].name;
            var idx = imgName.lastIndexOf(".");  
            if (idx != -1){
                var ext = imgName.substr(idx+1).toUpperCase();   
                ext = ext.toLowerCase( ); 
                 if (ext!='pdf' && ext!='doc' && ext!='docx'){

                }else{
                      this.addArr.push(file[i]);
                }   
            }else{

            }
       }
   }

通过change事件中的event.target.files就能获取到上传的文件了,在上面再次对获取的文件进行了类型限制。

(2)数据提交

获取到文件数据后,就需要将数据提交到后台,这里可以采用FormData的方式提交。

submitAddFile(){
           if(0 == this.addArr.length){
             this.$message({
               type: 'info',
               message: '请选择要上传的文件'
             });
             return;
           }

            var formData = new FormData();
            formData.append('num', this.addType);
            formData.append('linkId',this.addId);
            formData.append('rfilename',this.addFileName);
            for(var i=0;i<this.addArr.length;i++){
                formData.append('fileUpload',this.addArr[i]);
            }
          let config = {
            headers: {
              'Content-Type': 'multipart/form-data',
              'Authorization': this.token
            }
          };
          this.axios.post(apidate.uploadEnclosure,formData,config)
            .then((response) => {
                if(response.data.info=="success"){this.$message({
                        type: 'success',
                        message: '附件上传成功!'
                    });
                }
            })
        }

在进行数据提交的时候,有两点需要注意:formData对象和Content-Type,处理好着两点以后,就和其他的接口一样了。

2. el-upload

实现原理大同小异。

 <el-upload
 class="upload-demo"
 ref="upload"
 action="doUpload"
 :limit="1"
 :file-list="fileList"
 :before-upload="beforeUpload">
 <el-button slot="trigger" size="small" type="primary">选取文件</el-button>
 <a href="./static/moban.xlsx" rel="external nofollow" download="模板"><el-button size="small" type="success">下载模板</el-button></a>
 <!-- <el-button style="margin-left: 10px;" size="small" type="success" @click="submitUpload">上传到服务器</el-button> -->
 <div slot="tip" class="el-upload__tip">只能上传excel文件,且不超过5MB</div>
 <div slot="tip" class="el-upload-list__item-name">{{fileName}}</div>
 </el-upload> 
 <span slot="footer" class="dialog-footer">
 <el-button @click="visible = false">取消</el-button>
 <el-button type="primary" @click="submitUpload()">确定</el-button>
 </span>

上传之前比较文件大小。

beforeUpload(file){
 this.files = file;
 const extension = file.name.split('.')[1] === 'xls'
 const extension2 = file.name.split('.')[1] === 'xlsx'
 const isLt2M = file.size / 1024 / 1024 < 5
 if (!extension && !extension2) {
  this.$message.warning('上传模板只能是 xls、xlsx格式!')
  return
 }
 if (!isLt2M) {
  this.$message.warning('上传模板大小不能超过 5MB!')
  return
 }
 this.fileName = file.name;
 return false // 返回false不会自动上传
 },

手动上传确认提交。

submitUpload() {
 debugger
 console.log('上传'+this.files.name)
 if(this.fileName == ""){
  this.$message.warning('请选择要上传的文件!')
  return false
 }
 let fileFormData = new FormData();
 fileFormData.append('file', this.files, this.fileName);//filename是键,file是值,就是要传的文件,test.zip是要传的文件名
 let requestConfig = {
  headers: {
  'Content-Type': 'multipart/form-data'
  },
 }
 this.$http.post(`/basedata/oesmembers/upload?companyId=`+this.company, fileFormData, requestConfig).then((res) => {
  debugger
  if (data && data.code === 0) {
  this.$message({
  message: '操作成功',
  type: 'success',
  duration: 1500,
  onClose: () => {
  this.visible = false
  this.$emit('refreshDataList')
  }
  })
  } else {
  this.$message.error(data.msg)
  }
 }) 
 }