vue项目中实现预览pdf
1. iframe
<iframe :src="pdfSrc"></iframe>
data() {return {pdfSrc: 'http://192.168.0.254:19000/trend/2023/12/27/5635529375174c7798b5fabc22cbec45.pdf',}},iframe {width: 100%;height: calc(100vh - 132px - 2 * 20px - 160px);}
2. vue-pdf
npm i vue-pdf --save-dev
<!--* @Description: vue-pdf使用* @Author: mhf* @Date: 2023-12-28 11:37:30
-->
<template><div class="systemDescription"><div class="systemDescription-header">vue-pdf使用</div>
<lineH style="margin: 20px 0"/>
<div class="systemDescription-pdf"><pdfv-for="i in numPages":key="i":src="pdfSrc":page="i"></pdf></div></div>
</template>
<script>
import pdf from 'vue-pdf'
export default {name: 'systemDescription',components: { pdf },props: {},data() {return {pdfSrc:'http://192.168.0.254:19000/trend/2023/12/27/5635529375174c7798b5fabc22cbec45.pdf',numPages: undefined,}},methods: {},created() {},mounted() {let src = pdf.createLoadingTask(this.pdfSrc);src.promise.then(pdf => {this.numPages = pdf.numPages; // 解决vue-pdf默认只展示第一页的问题});}
}
</script>
<style lang="scss" scoped>
.systemDescription {padding: 50px 30px 40px;
&-header {font-size: 26px;font-family: Source Han Sans CN;font-weight: 700;color: #333;text-align: center;}
&-pdf {margin: 0 0 0 -24px;width: calc(100% + 50px);height: calc(100vh - 132px - 2 * 20px - 180px);overflow-y: auto;}
}
</style>
参考:解决vue-pdf默认只展示第一页的问题
使用vue-pdf展示静态PDF文件的时候(在线PDF可使用embed标签查看),常规操作之后发现只能加载第一页PDF,以下是解决方案:
vue-pdf使用过程如下:
$ yarn add vue-pdf
or
$ npm install vue-pdf
在组件中使用:
<template><pdf src=""></pdf>
</template>
<script>import pdf from 'vue-pdf'exprot default {component: {pdf}}
</script>
这个时候,多页的PDF只会显示第一页,这时各位可以去查看一下vue-pdf的源码,我们可以发现,它的实现过程是将PDF按页绘制在canvas上的,其页码数oage默认值是1,展示第一页的canvas。所以我们主要使用两种方式处理。
第一种是使用v-for循环加载所有页面:
<template><pdf src=""></pdf>
</template>
<script>import pdf from 'vue-pdf'exprot default {component: {pdf}}
</script>
这个时候,多页的PDF只会显示第一页,这时各位可以去查看一下vue-pdf的源码,我们可以发现,它的实现过程是将PDF按页绘制在canvas上的,其页码数oage默认值是1,展示第一页的canvas。所以我们主要使用两种方式处理。
第一种是使用v-for循环加载所有页面:
<template><div><pdfv-for="i in numPages":key="i":src="src":page="i"style="display: inline-block; width: 25%"></pdf></div>
</template><script>import pdf from 'vue-pdf'var loadingTask = pdf.createLoadingTask('https://cdn.mozilla.net/pdfjs/tracemonkey.pdf');export default {components: {pdf},data() {return {src: loadingTask,numPages: undefined,}},mounted() {this.src.promise.then(pdf => {this.numPages = pdf.numPages;});}
}</script>
这样有一个问题就是如果页数非常多,加载会很慢。
第二张是采用分页的形式:
<template><div class="onlineHelp cg-box"><div class="tools"><div class="page">第 {{pageNum}} /{{pageTotalNum}}页 </div><el-input v-model.number="goPageNum" style="width: 70px;margin-right: 8px"></el-input><el-button type="success" @click.stop="goPage"> 前往</el-button><el-button type="primary" @click.stop="prePage"> 上一页</el-button><el-button type="primary" @click.stop="nextPage"> 下一页</el-button></div><div class="pdf-box"><pdf ref="pdf":src="url":page="pageNum"@progress="loadedRatio = $event"@page-loaded="pageLoaded($event)"@num-pages="pageTotalNum=$event"@error="pdfError($event)"@link-clicked="page = $event"></pdf></div></div>
</template>
<script>
import pdf from 'vue-pdf'
export default {name: 'onlineHelp',components: {pdf},data() {return {url: `${process.env.VUE_APP_BASEURL}/help.pdf`,pageNum: 1,pageTotalNum: 1,// 加载进度loadedRatio: 0,curPageNum: 0,goPageNum: 1};},methods: {// 上一页函数,prePage() {var page = this.pageNumpage = page > 1 ? page - 1 : this.pageTotalNumthis.pageNum = page},// 下一页函数nextPage() {var page = this.pageNumpage = page < this.pageTotalNum ? page + 1 : 1this.pageNum = page},// 前往页数goPage() {if(!this.goPageNum || /\D/.test(this.goPageNum) || this.goPageNum < 1 || this.goPageNum > this.pageTotalNum) {this.$message.warning('输入页码有误')return}this.pageNum = this.goPageNum},// 页面加载回调函数,其中e为当前页数pageLoaded(e) {this.curPageNum = e},// 其他的一些回调函数。pdfError(error) {console.error(error)}}
};
</script>
<style lang="scss">
.onlineHelp {height: 100%;position: relative;display: flex;justify-content: center;.tools {position: absolute;top: 10px;right: 10px;z-index: 999;.page {display: inline-block;margin-right: 10px;}}.pdf-box {height: 100%;overflow: auto;width: 90%;}
}
</style>
二、
<template><div class="wrap"><pdf v-for="item in numPages" :key="item" :src="pdfSrc" :page="item"/></div>
</template>
<script>
import pdf from 'vue-pdf'
import CMapReaderFactory from 'vue-pdf/src/CMapReaderFactory.js'
export default {components:{pdf},data(){return{pdfUrl: "http://192.168.0.223:8080/pdf/预报.pdf",pdfSrc: "",numPages: "",}},mounted(){this.getTitlePdfurl();},methods:{getTitlePdfurl(){this.pdfSrc = pdf.createLoadingTask({ url: this.pdfUrl, CMapReaderFactory });//解决中文乱码问题this.pdfSrc.promise.then((pdf) => {this.numPages = pdf.numPages;})},}
}
</script>
<style lang="less" scoped>
.wrap{position: absolute;left: 0;right: 0;top: 0;bottom: 0;
}
</style>