vue使用vue-pdf预览pdf文件,带有换页、缩放、选择功能
1.安装
npm install --save vue-pdf
2.在需要用的页面引入
import pdf from 'vue-pdf'
3.带有放大、缩小、换页功能的用例
<template>
<div class="page-container">
<div class="main">
<pdf
:src="src"
:page="currentPage"
@progress="loadedRatio = $event"
@loaded="loadPdfHandler"
@num-pages="pageCount=$event"
@page-loaded="currentPage=$event"
ref="wrapper"
class="pdf"></pdf>
</div>
<ul class="footers">
<li :class="{select:idx==0}" @touchstart="idx=0" @touchend="idx=-1" @click="scaleD">
<p class="more-p">放大</p>
</li>
<li :class="{select:idx==1}" @touchstart="idx=1" @touchend="idx=-1" @click="scaleX">
<p class="small-p">缩小</p>
</li>
<li :class="{select:idx==2}" @touchstart="idx=2" @touchend="idx=-1" @click="changePdfPage(0)">
<p class="up-p">上一页</p>
</li>
<li :class="{select:idx==3}" @touchstart="idx=3" @touchend="idx=-1" @click="changePdfPage(1)">
<p class="down-p">下一页</p>
</li>
<li>
<p>当前第{{ currentPage }}页/共{{ pageCount }}页</p>
</li>
</ul>
</div>
</template>
<script>
import pdf from 'vue-pdf'
export default {
data() {
return {
currentPage: 1, // 当前页码
pageCount: 0, // 总页码
scale: 100,
idx: -1,
loadedRatio: 0,
src: 'https://dakaname.oss-cn-hangzhou.aliyuncs.com/file/2018-12-28/1546003237411.pdf'
}
},
created() {
this.src = pdf.createLoadingTask(this.src) // 处理一下跨域
},
components: {
pdf
},
methods: {
// 改变PDF页码,val传过来区分上一页下一页的值,0上一页,1下一页
changePdfPage(val) {
if(val === 0 && this.currentPage > 1) {
this.currentPage--;
}
if(val === 1 && this.currentPage < this.pageCount) {
this.currentPage++;
}
console.log(this.currentPage);
console.log(this.pageCount);
},
goBack() {
this.$router.go(-1);
},
// pdf加载时
loadPdfHandler(e) {
this.currentPage = 1; // 加载的时候先加载第一页
},
//放大
scaleD() {
this.scale += 5;
this.$refs.wrapper.$el.style.width = parseInt(this.scale) + "%";
},
//缩小
scaleX() {
if(this.scale == 100) {
return;
}
this.scale += -5;
this.$refs.wrapper.$el.style.width = parseInt(this.scale) + "%";
}
}
}
</script>
<style scoped>
.main {
overflow: hidden;
}
.footers {
position: fixed;
bottom: 0;
width: 100%;
display: flex;
z-index: 100;
color: #333;
border-top: 1px solid #f0f0f0;
line-height: 10px;
height: 30px;
}
.li {
text-align: center;
flex: 1;
padding: 5px;
cursor: pointer;
}
.ul {
list-style: none;
}
.more-p {
border-right: 1px solid #f0f0f0;
margin-right: 40px;
cursor: pointer;
}
.small-p {
margin-right: 40px;
cursor: pointer;
}
.up-p {
margin-right: 40px;
cursor: pointer;
}
.down-p {
border-radius: 0 none;
cursor: pointer;
margin-right: 50px;
}
</style>
效果
4.pdf不显示签名和红章
1.打开node_modules 文件夹下面的pdfjs-dist -> build -> pdf.worker.js
2.搜索data.fieldType,将if里面这句注释掉就可以
效果
**但是有个问题,这样配置后,显示有签章的页面就会报错Uncaught (in promise) DOMException: Failed to execute 'postMessage' on 'DedicatedWorkerGlobalScope': #<Promise> could not be cloned. 目前还未解决
4.笔记
1.src是pdf文件的路径,可以是相对地址、绝对地址、网址
2.:page当前pdf显示的页码,默认是1
3.@progress是pdf页面的加载进度(这个不是很懂)
4.@loaded pdf加载的时候执行
5.@num-page监听pdf的加载,获取pdf总页数
6.@page-loaded是pdf加载成功的回调(应该是范围换页后的页码)
5.在对话框显示pdf,并且带有选择功能
效果:
代码:
<template>
<div class="page-container">
<el-button @click="pdfDlgVisible = true">点击看看</el-button>
<el-dialog :visible.sync="pdfDlgVisible" title="pdf预览" height="calc(100vh - 10px)" class="pdf-dialog">
<div class="main">
<pdf
:src="src"
:page="currentPage"
@progress="loadedRatio = $event"
@loaded="loadPdfHandler"
@num-pages="pageCount=$event"
@page-loaded="currentPage=$event"
ref="wrapper"
class="pdf"></pdf>
</div>
<div slot="footer" class="footers">
<ul class="footer-ul">
<li>
<el-checkbox v-model="checkPage[currentPage]" class="radio-class" @change="checkClick(currentPage)">选择</el-checkbox>
</li>
<li :class="{select:idx==0}" @touchstart="idx=0" @touchend="idx=-1" @click="scaleD">
<p class="more-p">放大</p>
</li>
<li :class="{select:idx==1}" @touchstart="idx=1" @touchend="idx=-1" @click="scaleX">
<p class="small-p">缩小</p>
</li>
<li :class="{select:idx==2}" @touchstart="idx=2" @touchend="idx=-1" @click="changePdfPage(0)">
<p class="up-p">上一页</p>
</li>
<li :class="{select:idx==3}" @touchstart="idx=3" @touchend="idx=-1" @click="changePdfPage(1)">
<p class="down-p">下一页</p>
</li>
<li>
<p>当前第{{ currentPage }}页/共{{ pageCount }}页</p>
</li>
</ul>
<el-button @click="pdfDlgVisible = false">取消</el-button>
<el-button @click="commmit">确定</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import pdf from 'vue-pdf'
export default {
data() {
return {
currentPage: 1, // 当前页码
pageCount: 0, // 总页码
scale: 100,
idx: -1,
loadedRatio: 0,
src: 'https://dakaname.oss-cn-hangzhou.aliyuncs.com/file/2018-12-28/1546003237411.pdf',
pdfDlgVisible: false,
checkPage: [],
checkPageList: []
}
},
mounted() {
},
created() {
this.src = pdf.createLoadingTask(this.src) // 处理一下跨域
},
components: {
pdf
},
methods: {
// 改变PDF页码,val传过来区分上一页下一页的值,0上一页,1下一页
changePdfPage(val) {
if(val === 0 && this.currentPage > 1) {
this.currentPage--;
}
if(val === 1 && this.currentPage < this.pageCount) {
this.currentPage++;
}
for (let i=0; i<this.checkPageList.length; i++) {
let data = this.checkPageList[i]
if (data.page === this.currentPage) {
this.checkPage[this.currentPage] = data.check
break
} else {
this.checkPage[this.currentPage] = false
}
}
},
// pdf加载时
loadPdfHandler(e) {
this.currentPage = 1; // 加载的时候先加载第一页
},
//放大
scaleD() {
this.scale += 5;
this.$refs.wrapper.$el.style.width = parseInt(this.scale) + "%";
},
//缩小
scaleX() {
if(this.scale == 100) {
return;
}
this.scale += -5;
this.$refs.wrapper.$el.style.width = parseInt(this.scale) + "%";
},
checkClick: function(data) {
if (this.checkPageList.length === 0) {
this.checkPageList.push({
page: data,
check: this.checkPage[data]
})
} else {
for (let i=0; i<this.checkPageList.length; i++) {
if (this.checkPageList[i].page === data) {
this.checkPageList[i].check = this.checkPage[data]
break
} else {
this.checkPageList.push({
page: data,
check: this.checkPage[data]
})
break
}
}
}
for (let i=0; i<this.checkPageList.length; i++) {
let data1 = this.checkPageList[i]
for (let j=i + 1; j<this.checkPageList.length; j++) {
let data2 = this.checkPageList[j]
if (data1.page === data2.page) {
this.checkPageList.splice(i, 1)
}
}
}
},
commmit: function() {
console.log(this.checkPageList);
}
}
}
</script>
<style scoped>
.main {
overflow: hidden;
}
.li {
text-align: center;
flex: 1;
padding: 5px;
cursor: pointer;
}
.footer-ul {
bottom: 0;
display: flex;
/* margin-left: 20px; */
margin: 0px;
z-index: 200;
list-style: none;
}
.more-p {
border-right: 1px solid #f0f0f0;
margin-right: 40px;
cursor: pointer;
}
.small-p {
margin-right: 40px;
cursor: pointer;
}
.up-p {
margin-right: 40px;
cursor: pointer;
}
.down-p {
border-radius: 0 none;
cursor: pointer;
margin-right: 50px;
}
</style>
<style>
.pdf-dialog .el-dialog__body {
height: calc(100vh - 450px);
overflow: auto;
padding: 0px;
}
.pdf-dialog .el-dialog__header {
overflow: auto;
padding: 10px 0px 2px 20px;
}
.radio-class .el-checkbox__inner {
height: 20px;
width: 20px;
}
.radio-class .el-checkbox__label {
font-size: 25px;
}
</style>