前端上传el-upload、原生input本地文件pdf格式(纯前端预览本地文件不走后端接口)

发布于:2025-05-16 ⋅ 阅读:(11) ⋅ 点赞:(0)

前端实现本地文件上传与预览(PDF格式展示)不走后端接口

实现步骤

第一步:文件选择

使用前端原生input上传本地文件,或者是el-upload组件实现文件选择功能,核心在于文件渲染处理。(input只不过可以自定义样式)

 <div v-if="!uploaded" v-loading="loading" class="upload_box">
 <p @click="openFileSelector()">
          <img src="@/assets/上传文件.png" 
          @dragover.prevent 
          @drop.prevent="onDrop" 
          @dragenter.prevent="onDragEnter"
          @dragleave.prevent="onDragLeave" 
           style="padding-left: 30px" />
          <input 
            :id="'file' + title" 
            type="file" 
            ref="fileInput" 
            single 
            accept=".pdf" 
            @change="handleFileSelect"
            style="display: none" />
          <span class="card_text" for="file">请上传本地文件</span>
          <span class="card_text" style="font-weight: 400">支持选择、拖拽上传PDF</span>
        </p>
    </div>

第二步:文件处理

通过URL.createObjectURL(file)将本地文件转换为URL进行访问。

<script>
 methods: {
 //点击上传的方法
 openFileSelector() {
      // console.log('aaaa');
      const filedox = document.getElementById("file" + this.title);
      filedox.click();
      //this.fileInputRef.click();
    },
  }
  //拖拽的方法
    onDrop(event) {
      // console.log('ondrop',event)
      this.isDragging = false;
      const file1 = event.dataTransfer.files[0];
      this.uploaded = true;
      this.loading = false
      if (file1 && file1.type === 'application/pdf') {
      //重点是这里将文件转换成本地url地址去访问
        const blobUrl = URL.createObjectURL(file1);
        // http://192.168.203.213:8080
        // console.log('blobUrl',blobUrl)
        //将url返回给标签渲染的
        this.pdfPreview = blobUrl
      }
      for (let i = 0; i < files.length; i++) {
        const file = files[i];
        if (
          file.type === "application/pdf" ||
          file.type === "application/msword" ||
          file.type ===
          "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
        ) {
          let transform_type_val;
          if (files[0].type === "application/pdf") {
            if (this.routerType == 'word') {
              transform_type_val = 'pdf2word';
              file.transform_type = transform_type_val;
            } else if (this.routerType == 'excel') {
              transform_type_val = 'risk';
              file.extract_type = transform_type_val;
            }
            // console.log('pdf',file.transform_type)
          }
          this.selectedFiles.push(file);
        }
      }
      // this.uploadFiles();
      this.fileInputRef.value = null;
    },
   //input事件 和 拖拽事件一致
    handleFileSelect(event) {
      const file1 = event.target.files[0];
      if (file1 && file1.type === 'application/pdf') {
        this.uploaded = true;
        this.loading = false
        const blobUrl = URL.createObjectURL(file1);
        // http://192.168.203.213:8080
        // console.log('blobUrl',blobUrl)
        this.pdfPreview = blobUrl
      } else {
        this.$message.error('仅支持pdf格式文件');
        return;
      }
      // console.log('触犯上传',files);
      // for (let i = 0; i < files.length; i++) {
      // const file = files[i];
      const file = files[0];
      const regx = /\.docx$/i;
      const regc = /\.doc$/i;
      // console.log('file==',file)
      if (
        file.type === "application/pdf" ||
        file.type === "application/msword" ||
        file.type === "application/vnd.openxmlformats-officedocument.wordprocessingml.document" ||
        regx.test(file.name) || regc.test(file.name)
      ) {
        let transform_type_val;
        if (files[0].type === "application/pdf") {
          if (this.routerType == 'word') {
            transform_type_val = 'pdf2word';
            file.transform_type = transform_type_val;
          } else if (this.routerType == 'excel') {
            transform_type_val = 'risk';
            file.extract_type = transform_type_val;
          }
          // console.log('pdf',file.transform_type)
        }
        //
        this.selectedFiles.push(file);
        // console.log('this.selectedF/iles',this.selectedFiles)
      }
      // }
      // this.uploadFiles();
      this.fileInputRef.value = null;
    },
     //走接口的方法
    async uploadFiles() {
      // console.log('this.selecte/dFiles==',this.selectedFiles)
      if (this.selectedFiles.length === 0) {
        this.$message.warning("没有选择要上传的文件");
        return;
      }
      const pattern = /http:\/\/oss:/g;
      // const pattern = /http:\/\/127.0.0.1:/g;
      const formData = new FormData();
      let ConvertPDF = false;
      // console.log('this.selectedFiles===',this.selectedFiles)
      this.selectedFiles.forEach((file) => {
        // if(file.transform_type=='pdf2word'){
        //   ConvertPDF = true
        // }
        formData.append("file", file);
        // console.log('2656251==',)
        if (this.routerType == 'word') {
          formData.append("transform_type", file.transform_type);
        } else if (this.routerType == 'excel') {
          formData.append("extract_type", file.extract_type);
        }
      });
      // console.log('didiididi==',)
      const aiToken = sessionStorage.getItem("aiToken");
      const xtpToken = sessionStorage.getItem("xtpToken");
      let apiUrl
      if (this.routerType == 'word') {
        apiUrl = '/api/v1/transform/create'
        // apiUrl = '/api/api/v1/transform/create'
      } else if (this.routerType == 'excel') {
        apiUrl = '/api/v1/extract/create'
        // apiUrl = '/api/api/v1/extract/create'
      }
      try {
        // console.log('上传')
        const response = await axios.post(
          apiUrl,
          formData,
          {
            headers: {
              "Content-Type": "multipart/form-data",
              token: aiToken ? aiToken : xtpToken,
            },
          }
        );
        this.loading = true
        this.$message.success("文件上传成功");
        //这应该获得上传好文件的id
        // console.log('didi==',response.data.data);
        let id = response.data.data.id;
        this.$emit('upload', id)
        if (!id) {
          this.$message.warning('请上传文件')
          return
        } else {
          const fileId = id
          if (this.routerType == 'word') {
            startTransform({ transform_task_id: fileId }).then((res) => {
              // console.log('转换',res);
            })
          } else if (this.routerType == 'excel') {
            startExtract({ extract_task_id: fileId }).then((res) => {
              // console.log('转换',res);
            }).finally(() => {
              console.log("无论如何都执行")
            });
          }
          if (this.routerType == 'word') {
            this.$router.push('/wordTable')
          } else if (this.routerType == 'excel') {
            this.$router.push('/excelTable')
          }
        }
        let src = '';
        let errorMsg = '';
        // 判断是否转pdf走转pdf的接口
        if (ConvertPDF) {
          this.timer = setInterval(() => {
            detai(id).then((res) => {
              src = res.data.pdf_filepath;
              errorMsg = res.data.convert_error
              if (src) {
                const a = src.replace(pattern, `http://10.223.33.105:`);
                this.ispdf = true;
                this.pdfsrc = a;
                this.uploaded = true;
                this.loading = false
                clearInterval(this.timer)
              }
              if (errorMsg) {
                this.$message.error("文件转换失败" + errorMsg);
              }
            })
          }, 3000);
        } else {
          //在这获取要展示的pdf地址
          // file_url
          // console.log('在这获取要展示的pdf地址',response.data)
          src = response.data.data.file_url;
          // const a = src.replace(pattern, `http://192.168.202.231:`);
          const a = src.replace(pattern, `http://10.223.33.105:`); 
          this.ispdf = true;
          this.pdfsrc = a;
          this.uploaded = true;
          // console.log('pdfsrc==',this.pdfsrc)
        }
      } catch (error) {
        // this.uploaded = true;
        this.$message.error("文件上传失败" + error.message);
      }
    },
     // 重新选择
    reselect() {
      this.$confirm("重新选择比对结果会被清空?", "提示", {
        distinguishCancelAndClose: true,
        confirmButtonText: "确定",
        cancelButtonText: "取消",
      })
        .then(() => {
          this.uploaded = false;
          // console.log("dada");
          this.selectedFiles = []
          this.pdfsrc = ''
          this.loading = false
          this.$emit('upload', null)
          if (this.timer) {
            clearInterval(this.timer)
          }
        })
        .catch(() => { });
    },
</script>

第三步:实现本地文件渲染的 <embed> 标签

渲染机制:利用浏览器内置的 PDF 插件进行渲染

<embed v-if="pdfPreview" id="pdfPreview" :src="pdfPreview" width="100%" />

效果图
在这里插入图片描述

在这里插入图片描述