Loading

vue页面内预览docx/pdf/xlsx

1.页面

<div ref="docsRef" id="fileView" class="view" :style="{ height: viewHeight + 'px' }"></div>
    <div v-if="fileType == 'pdf'" v-loading="loading" class="pdf-bg" ref="pdfRef" :style="{ height: viewHeight + 'px' }">
      <pdf style="width: 70%; margin: auto" v-for="i in pdfPageNum" :key="i" :src="fileUrl" :page="i"
        @progress="pdfProgress(i)" @page-loaded="loadPdfHandler"></pdf>
    </div>
    <div v-if="fileType == 'docx' || fileType == 'xlsx'" ref="docsRef" id="fileView" class="view"
      :style="{ height: viewHeight + 'px' }"></div>
    <iframe v-if="fileType == 'doc'" ref="iframe" id="iframe" frameborder="0" :src="fileUrl" style="width: 100%;"
      :style="{ height: viewHeight + 'px' }"></iframe>

 

2.js

<script>
import { excelView, filePreview } from "@/utils/fileUtils";
import { saveAs } from "file-saver";
import pdf from 'vue-pdf';
import { renderAsync } from "docx-preview";

export default {
  components: { pdf },
  name: 'file-preview',
  data () {
    return {
      title: '文件预览',
      open: false,
      loading:false,
      viewHeight: 500,
      info: { url: null, blob: null, filename: null, },
      pdfPageNum: 0,
      fileUrl: '',
      fileType: '',
    }
  },
  created () {
  },
  mounted () {
    this.doLayout()
    //根据屏幕缩放自动获取页面宽高
    window.onresize = () => {
      return (() => {
        this.doLayout()
      })()
    }
  },
  methods: {
    init (info) {
      this.reset();
      this.info = info;
      this.open = true;
      if (info.filename.includes('.docx')) {
        this.fileType = 'docx'
        this.docView(info.blob)
      } else if (info.filename.includes('.pdf')) {
        this.fileType = 'pdf'
        this.pdfView(info.url)
      }
      else if (info.filename.includes('.xlsx')) {
        this.fileType = 'xlsx'
        excelView(info.url)
      }
      else if (info.filename.includes('.doc')) {
        this.fileType = 'doc'
        this.fileUrl = filePreview(info.url)
      }
    },
    // 渲染doc
    docView (blob) {
      this.$nextTick(() => {
        renderAsync(blob, this.$refs.docsRef); // 渲染到页面预览
      })
    },
    pdfView (fileUrl) {
      this.open = true;
      this.openPdf(fileUrl)
    },
    // 渲染pdf
    openPdf (fileUrl) {
      this.loading = true;
      let loadingTask = pdf.createLoadingTask(fileUrl);
      loadingTask.promise
        .then((pdf) => {
          this.$nextTick(() => {
            this.fileUrl = loadingTask;
            this.pdfPageNum = pdf.numPages || 0;
            this.$forceUpdate();
          });
        })
        .catch((err) => {
          this.loading = false;
        });
    },

    pdfProgress (index) {
      if (index === 1) {
        this.loading = true;
      }
    },

    loadPdfHandler (e) {
      if (this.pdfPageNum === e) {
        this.loading = false;
      }
    },
    // 打印
    onPrint () {
      let wpt = document.getElementById('fileView');
      let newContent = wpt.innerHTML;
      let oldContent = document.body.innerHTML;
      document.body.innerHTML = newContent;
      window.print(); //打印方法
      window.location.reload()
      document.body.innerHTML = oldContent;
    },
    // 下载
    download () {
      saveAs(this.info.blob, this.info.filename);
    },
    doLayout () {
      this.viewHeight = document.documentElement.clientHeight - 300;
    },
    cancel () {
      this.open = false
      this.reset()
    },
    reset () {
      this.fileType = ''
      this.info = { url: null, blob: null, filename: null };
      if (this.$refs.docsRef) {
        this.$refs.docsRef.innerHTML = '';
      };
    }
  },
}
</script>

3.css

<style lang="scss" scoped>
.view {
  width: 100%;
  overflow-y: auto;
}

.pdf-bg {
  width: 100%;
  margin: 0 auto;
  overflow-y: auto;
  background-color: #808080;
}

.luckysheet {
  height: 100%;
  width: 80%;
}
</style>

 

posted @ 2022-06-23 11:21  请叫我王小胖  阅读(3978)  评论(0编辑  收藏  举报