解决本地上传文件,下载PDF失败或者只打开不下载的问题

发布时间 2023-07-10 15:30:00作者: ChoZ

情况:前端上传文件(不调用接口存储文件),存放至列表供下载(文件区别pdf和其他文件格式不同处理情况)

1.上传组件逻辑,获取上传的文件

<template>
  <div class="uploading-wrap">
    <ak-upload
      name="file"
      ref="upload"
      :loading="showPreViewLoading"
      :disabled="showPreViewLoading"
      :customRequest="true"
      uploadBtnText="上传文件"
      @error="handleUploadError"
      @beforeUpload="handleBeforeUpload">
      <template>
        <span v-if="showUploadDetail" class="result-file ak-omit-1">{{uploadFile.name}}</span>
        <span v-else class="result-file">上传文件</span>
      </template>
    </ak-upload>
    <i v-if="showUploadDetail" class="icon-shanchu clearIcon" @click.stop="delFile"></i>
  </div>
</template>

<script>

export default {
  data() {
    return {
      uploadFile: null, // 上传成功的文件列表
      showUploadDetail: false, // 显示上传结果
      showPreViewLoading: false // 预览loading
    }
  },
  methods: {
    handleBeforeUpload(e) {
      const files = e.target.files // kb
      if (!files || !files.length === 0) {
        this.showUploadDetail = false
        return
      }
      const file = files[0]
      // const { name } = file
      const SIZE = 1024 * 1024 * 60 // 60M
      // const uploadTypes = 'xls,xlsx'
      // const type = name.split('.').slice(-1)
      if (e.target.files.length > 1) {
        this.$msg('附件上传不能超过1个', {icon: 3})
        return
      }
      // if (uploadTypes.indexOf(type) === -1) {
      //   this.$msg('上传的附件类型不符合要求', {icon: 3})
      //   return
      // }
      if (file.size >= SIZE) {
        this.$msg('文件太大', {icon: 3})
        return
      }

      this.uploadFile = file
      this.showUploadDetail = true
      this.$emit('change', file)
      return false
    }
  }
}
</script>

2.编写PDF下载需使用js获取下载流,重新生成本地下载链接,再触发下载事件函数

function getFile(url,fileName){
    var httpRequest = new XMLHttpRequest();
    //指定响应类型,这决定了浏览器对返回内容的解析方式,设置为空或者text会作为字符解析、json会作为json解析,blob和arraybuffer会作为字节流解析
    httpRequest.responseType ='arraybuffer';
    httpRequest.open('GET', url, true);
    httpRequest.onload  = function () {
        if (httpRequest.readyState == 4 && httpRequest.status == 200) {
            //只有responseType为空或者text,才会使用responseText获取内容,其他情况                        httpRequest.response就是你需要的不含http头的返回内容
            var content = httpRequest.response;
            var elink = document.createElement('a');
            elink.download = fileName;
            elink.style.display = 'none';
            var blob = new Blob([content]);
            //创建指向内存中字节流的链接
            elink.href = URL.createObjectURL(blob);
            document.body.appendChild(elink);
            elink.click();
            document.body.removeChild(elink);
        }
    };
    httpRequest.send();
}

3.编写下载上传的文件的方法(包括PDF文件及其他文件)

    downLocalFile(downFile, local = false) {
      const { name } = downFile
      const tempLink = document.createElement('a')
      const objectUrl = URL.createObjectURL(downFile) // 生成本地Url
      tempLink.href = objectUrl
      tempLink.name = downFile.name
      if (name.substr(name.lastIndexOf('.') + 1) === 'pdf') {
        // tempLink.target = '_blank'
        // tempLink.name += '.pdf'
        this.getFile(objectUrl, tempLink.name)
        return
      }
      document.body.appendChild(tempLink)
      tempLink.click()

      document.body.removeChild(tempLink)
      URL.revokeObjectURL(objectUrl)
    },

4.使用方法:

this.downLocalFile(file)  // file是上传组件抛出的文件