vue项目中实现预览pdf

2023-12-28 12:15:34

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">
 ? ? ?<pdf
 ? ? ? ? ? v-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>
 ? ? ? ?<pdf
 ? ? ? ? ? ?v-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.pageNum
 ? ? ?page = page > 1 ? page - 1 : this.pageTotalNum
 ? ? ?this.pageNum = page
 ?  },
 ? ?// 下一页函数
 ? ?nextPage() {
 ? ? ?var page = this.pageNum
 ? ? ?page = page < this.pageTotalNum ? page + 1 : 1
 ? ? ?this.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>

文章来源:https://blog.csdn.net/m0_74149462/article/details/135265464
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。