文件上传和下载

139 阅读1分钟

一、form-data的方式

1、上传

<sc-upload
    ref="uploadRef"
    :action="uploadUrl"
    accept=".xls,.xlsx"
    :http-request="uploadScheme"
    :show-file-list="false"
    :on-success="onSuccess">
    <sc-button>
      <span class="icon icosfont">&#xe716;</span>
      导入
    </sc-button>
  </sc-upload>
  
   uploadUrl: '/intellitbi/import_acs_data',
   
   async uploadScheme(content) {
      var form = new FormData(); //  创建formdata对象,放到请求的body中
      form.append('file', content.file);
      form.append('user', getCookie('userName'));
      form.append('Authorization', getCookie('token'));
      try {
        this.onProcess();
        const res = await import_acs_data(form);
        this.downRes = res.data;
        this.$message({
          type: 'success',
          message: '导入成功!'
        });
        this.showRes = true;
        this.processMess && this.processMess.close();
      } catch (err) {
        this.$message({
          type: 'error',
          message: '导入失败!'
        });
      }
    },
  

2、下载

 <span class="link" @click="download">点击下载</span>
 
  download() {
      this.fileUrls.forEach((fileUrl) => {
        const res = feedbackDownload({
          fileName: fileUrl
        })
      })
    }
  
 export function feedbackDownload(data) {
  return fetch.downloadPostFile('/path/feedback/download', data)
}

/**
 * 直接下载文件
 * 不请求数据,直接拼装url放入a标签
 * 使用post方法
 */
const downloadPostFile = async (url, data = {}, msg = '无法下载文件') => {
  try {
    const result = await postAll(url, data, { responseType: 'blob' })
    const fileName = getContentDispositionFileName(result.headers)
    saveBlobFile(result.data, fileName)
    return Promise.resolve(result)
  } catch (error) {
    Message({
      message: msg,
      type: 'error',
      showClose: true,
      duration: 2000
    })
    return Promise.reject(error)
  }
}
const postAll = (url, data = {}, options = {}) => 
  fetchAll({ url, method: 'post', data, ...options }) // 返回所有 包括header
const fetchAll = (options) =>
  new Promise((resolve, reject) => {
    request(options)
      .then((res) => resolve(res))
      .catch((err) => reject(err))
  })
// 解码并返回结果
export const getContentDispositionFileName = (headers) => {
  const fileNameStr = headers['content-disposition'].split(';')[1]
  const fileName = getValueFromPairs(fileNameStr, 'filename')
  return decodeURI(fileName)
}

// 保存文件
export const saveBlobFile = (blobStream, fileName) => {
  const blob = new Blob([blobStream])
  const fileUrl = window.URL.createObjectURL(blob)
  // 如果是ie
  if ('msSaveOrOpenBlob' in navigator) {
    window.navigator.msSaveOrOpenBlob(blob, fileName)
  } else {
    // 其他浏览器用<a>模拟点击
    const link = document.createElement('a')
    link.href = fileUrl
    link.setAttribute('download', fileName)
    link.click()
  }
  window.URL.revokeObjectURL(fileUrl)
}

二、application/octet-stream的方式

1、上传

 <sc-upload
    ref="uploadRef"
    class="upload-demo"
    :action="uploadUrl"
    :file-list="fileList"
    :auto-upload="false"
    :on-change="handleFileChange"
    :limit="1"
  >
    <sc-button size="small"> <i class="icosfont">&#xe786;</i>上传文件</sc-button>
  </sc-upload>
  
async saveUploadHandler() {
  const file = this.$refs.uploadRef.fileList[0]
  const requestData = file.raw // 我们的组件把二进制文件包了一层,接口要求拿出来
  try {
    const res = await fetch.postOs(this.uploadUrl, requestData, {
      headers: {
        Authorization: getCookie('token'),
        orgid: this.$store.state.app.orgId,
        'Content-Type': 'application/octet-stream',
        'my-filename': encodeURIComponent(file.name) // 通过自定义请求头字段传文件名
      },
     
    })
    this.$message.success('导入成功')
    this.uploadVisible = false
  } catch (err) {
    console.error(err)
  }
},

2、下载

async saveDownloadHandler() {
  const res = await gaode_down({
    adcode: this.selectAdcode,
    district: this.selectDistrict,
    dateExportType: this.dataType,
    startDate: this.value1 ? moment(this.value1[0]).format('YYYY-MM-DD') : '',
    endDate: this.value1 ? moment(this.value1[1]).format('YYYY-MM-DD') : ''
  })
  this.downloadVisible = false
}
export function gaode_down(data) {
  return fetch.downloadOctetStreamFile('/gaodeDataProcess/gaode/down', data)
}
const downloadOctetStreamFile = async (url, data = {}, msg = '无法下载文件') => {
  try {
    const result = await postAll(url, data, { responseType: 'blob' })
    const fileName = getHeadersContentDispositionFileName(result.headers)
    saveBlobFile(result.data, fileName)
    return Promise.resolve(result)
  } catch (error) {
    Message({
      message: msg,
      type: 'error',
      showClose: true,
      duration: 2000
    })
    return Promise.reject(error)
  }
}
export const getHeadersContentDispositionFileName = (headers) => {
  const fileNameStr = headers['content-disposition'].split('_')
  fileNameStr.shift()
  const fileName = fileNameStr.join('_')
  return decodeURI(fileName)
}