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>