后端返回二进制文件流,前端处理预览文件和下载文件

977 阅读1分钟
// 获取文件二进制数据并转换临时路径
export const getFileBlob = (data) => {
  return server({
    url: " ",
    method: "get",
    params: data,
    responseType: "blob",
  }).then((res) => {
    let metaType = "application/pdf";
    if (data.type == "docx") {
      metaType =
        "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
    }
    if (data.type == "doc") {
      metaType = "application/msword";
    }
    let fileURL = null;
    let blob = new Blob([res], { type: metaType });
    if (window.createObjectURL != undefined) {
      // basic
      fileURL = window.createObjectURL(blob);
    } else if (window.webkitURL != undefined) {
      // webkit or chrome
      try {
        fileURL = window.webkitURL.createObjectURL(blob);
      } catch (error) {
        console.log(error);
      }
    } else if (window.URL != undefined) {
      // mozilla(firefox)
      try {
        fileURL = window.URL.createObjectURL(blob);
      } catch (error) {
        console.log(error);
      }
    }

    return fileURL;
  });
};

上面就是点击预览按钮发送请求,data为参数,我项目中是传入{id:xx,type:xx},id就是当前文件id,type就是文件类型,这边是pdf或者docx

<el-dialog :visible.sync="dialog" title="预览" width="800px">
    <div class="qz-pdf-container" ref="pdfContainer">
      <div v-if="fileType == 'pdf' && dialog">
        <pdf
          :src="url"
          :page="currentPage"
          @num-pages="pageCount = $event"
          @page-loaded="currentPage = $event"
          @loaded="loadPdfHandler"
        >
          ></pdf
        >
      </div>
      <div
        v-if="fileType !== 'pdf' && dialog"
        v-html="wordText"
        class="qz-word"
      ></div>
    </div>
    <div class="footer" v-if="pageCount !== 1 && pdfType == 'pdf'">
      <el-button
        type="primary"
        icon="el-icon-arrow-left"
        size="mini"
        @click="changePdfPage(0)"
        >上一页</el-button
      >
      <span> {{ currentPage }} / {{ pageCount }}</span>
      <el-button type="primary" size="mini" @click="changePdfPage(1)"
        >下一页<i class="el-icon-arrow-right el-icon--right"></i
      ></el-button>
    </div>
  </el-dialog>

这是预览弹窗的一个组件,自己封装的,需要引入

<script>
import pdf from "vue-pdf";
import mammoth from "mammoth";
export default {
  name: "QzLookpdf",
  components: {
    pdf,
  },
  props: {
    url: String,
    visible: {
      type: Boolean,
      default: false,
    },
    pdfType: String,
  },
  data() {
    return {
      numPages: 0,
      currentPage: 0, // pdf选中文件页码
      pageCount: 0, // pdf文件总页数
      loading: false,
      wordText: "",
    };
  },
  computed: {
    fileType() {
      return this.pdfType;
    },
    dialog: {
      get() {
        return this.visible;
      },
      set(val) {
        this.$emit("update:visible", val);
      },
    },
  },
  watch: {
    url: {
      handler(url) {
        this.loading = true;
        this.getNumPages(url);
      },
      immediate: true,
    },
    visible: {
      handler(v) {
        if (!v) this.currentPage = 1;
      },
    },
  },
  methods: {
    // pdfLoaded() {
    //   this.loading = false;
    // },
    getNumPages(url) {
      if (!url) return;
      if (this.fileType !== "pdf") return this.getWordText();
      let loadingTask = pdf.createLoadingTask(url);
      loadingTask.promise.then((pdf) => {
        this.numPages = pdf.numPages;
      });
    },
    getWordText() {
      const xhr = new XMLHttpRequest();
      xhr.open("get", this.url, true);
      xhr.responseType = "arraybuffer";
      xhr.onload = () => {
        this.loading = false;
        if (xhr.status == 200) {
          mammoth
            .convertToHtml({ arrayBuffer: new Uint8Array(xhr.response) })
            .then((resultObject) => {
              this.$nextTick(() => {
                this.wordText = resultObject.value;
              });
            })
            .catch((err) => {
              console.log("解析失败::::::::::::::::", err);
            });
        }
      };
      xhr.send();
    },

    // 改变PDF页码,val传过来区分上一页下一页的值,0上一页,1下一页
    changePdfPage(val) {
      if (val === 0 && this.currentPage > 1) {
        this.currentPage--;
        this.$refs.pdfContainer.scrollTop = 0;
      }
      if (val === 1 && this.currentPage < this.pageCount) {
        this.currentPage++;
        this.$refs.pdfContainer.scrollTop = 0;
      }
    },
    // pdf加载时
    loadPdfHandler() {
      this.currentPage = 1; // 加载的时候先加载第一页
    },
  },
};
</script>

不过这个mammoth解析不了doc文件,所以目前也是不知道怎么解决

www.csdn.net/tags/NtTakg…