场景:前端在实现pdf预览时,需要实现分页预览和缩放功能,同时需要保证pdf的清晰度。
但因为种种原因,不可以接通过iframe标签将pdf文件引入,让用户直接使用浏览器自带的pdf预览的相关工具。而是需要自己通过代码实现上述两个功能。
注:若可以直接使用iframe引入 是比较简单的 关于iframe直接引入的方式可见这里
vue中运用vue-pdf实现pdf分页预览及缩放(可解决pdf预览不清晰问题)
实现效果:
本次封装的组件的实现效果展示如下
实现思路:
1. 使用vue-pdf插件来实现预览功能。
2. 上一页/下一页按钮的点击事件中,改变当前当页码,实现翻页功能。
3. 缩放按钮的点击事件中,改变pdf预览插件所在容器的css样式—–transform:scale(),实现缩放功能。
注: 也曾试过直接去改变pdf预览插件所在容器的宽度来实现缩放效果,这种实现方案较为简单,动态改变容器的width就可以。但是若pdf的内容中主要是文字,就会出现文字清晰度不够的问题。哈哈哈 残酷!
实现步骤:
1. 安装依赖
npm install –save vue-pdf
2. 在需要的页面,引入插件
import pdf from 'vue-pdf'
3. 组件封装完整代码展示
html部分
<template>
<div
class="pdf-preview-out"
v-loading="boxLoading"
>
<!-- 上部 外层容器 用于滚动-->
<div class="scroll-box">
<!-- 用于截取调缩放后的空白区域 -->
<div class="pdf-box">
<!-- pdf预览区域(会被缩放) -->
<div
:style="getPdfSize()"
class="pdf-scale-box"
>
<!-- 预览组件 -->
<pdf
:src="url"
:page="currentPage"
@num-pages="getTotalPage"
@page-loaded="pageLoaded"
@loaded="mountedLoaded"
>
</pdf>
</div>
</div>
</div>
<!-- 底部操作栏 -->
<div class="bottom-tools">
<div>
共 {
{ pageTotal }} 页
</div>
<div class="page">
<el-button
round
type="primary"
:disabled="currentPage === 1"
@click="chengPage"
>
上一页
</el-button>
<!-- 页码展示及跳转 -->
<el-button
round
type="primary"
:disabled="currentPage === pageTotal"
@click="chengPage('+')"
>
下一页
</el-button>
</div>
<div class="scale">
<el-button
type="primary"
icon="el-icon-minus"
circle
:disabled="(pageScale - 0.1) < 0.3"
@click="scalePage"
>
</el-button>
<el-button
type="primary"
icon="el-icon-plus"
circle
:disabled="(pageScale + 0.1) > 1"
@click="scalePage('+')"
>
</el-button>
</div>
</div>
</div>
</template>
JS部分
<script>
// 插件引入
import pdf from 'vue-pdf'
export default {
components: {
pdf
},
props: {
// pdf预览的地址 由父组件中传入 也可在本组件中直接赋值
url: {
type: String,
default: ''
},
},
data() {
return {
// 总页数
pageTotal: 0,
// 当前页
currentPage: 1,
// 缩放比例
pageScale: 0.8,
// 遮罩
boxLoading: true,
pageChangeTimer: null,
}
},
methods: {
// 获取到pdf总页数时触发 会传入总页数
getTotalPage(page) {
this.pageTotal = page
},
// 初始化加载完毕触发
mountedLoaded() {
// 去除遮罩
this.boxLoading = false
},
// 每加载完成一页时触发(初始化/翻页时均会触发)
pageLoaded() {
// 重新设置pdf预览区域容器外容器的尺寸
this.setPdfBoxSize()
},
// 设置pdf预览区域容器的缩放尺寸
getPdfSize() {
return {
transform: `scale(${this.pageScale})`
}
},
// 点击缩放时触发
scalePage(type) {
// 改变缩放比例
let sacle = 0
if (type === '+') {
sacle = this.pageScale + 0.1
} else {
sacle = this.pageScale - 0.1
}
// 可能会涉及js的精度损失 保留一位小数即可
this.pageScale = Number(sacle.toFixed(1))
// 缩放后pdf预览区域容器中会有留白 重新设置pdf预览区域容器外容器的尺寸
this.setPdfBoxSize()
},
// 方法 翻页
chengPage(type) {
// 防抖 0.5秒内不再次触发时执行
if (this.pageChangeTimer) {
clearTimeout(this.pageChangeTimer)
}
// 执行翻页
this.pageChangeTimer = setTimeout(() => {
if (type === '+') {
this.currentPage+=1
} else {
this.currentPage-=1
}
// 翻页后将滚动条归位到顶部
this.scrollbarReset()
this.pageChangeTimer = null
}, 500)
},
// 方法 滚动条归位到顶部
scrollbarReset() {
let boxDom = document.querySelector('.scroll-box')
boxDom.scrollTop = 0
},
// 方法 设置pdf预览区域容器外容器的尺寸
setPdfBoxSize() {
// 缩放后 pdf的显示上会缩小 但元素的实际占地尺寸不会变化(仍是原尺寸) 导致可能会出现部分区域留白 通过改变pdf预览区域容器外容器的尺寸 来将留白区域hidden
// 获取pdf的原尺寸
let boxDom = document.querySelector('.pdf-scale-box')
// 获取要设置尺寸的元素dom
let setDom = document.querySelector('.pdf-box')
// 如有缩放 高度根据缩放比例变化(48px是预留的上下外边距)
if (this.pageScale !== 1 && boxDom && setDom) {
setDom.style.height = `${boxDom.clientHeight * this.pageScale + 48}px`
} else {
setDom.style.height = ''
}
// console.log(this.pageScale)
// console.log(boxDom.clientWidth * this.pageScale)
}
}
}
</script>
css部分
<style lang="scss" scoped>
.pdf-preview-out {
// 高度为占满父组件中的外层容器(若不需要在父组件中设置高度 也可以在本组件中直接设置为所需值)
height: 100%;
// border: 1px solid #909;
&, div {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
// 滚动容器
.scroll-box {
// 高度按比例 溢出滚动
height: calc(100% - 50px);
overflow: auto;
border: 2px solid #c0d8f3;
border-bottom: none;
border-radius: 6px;
background-color: #eeeeee;
// 滚动条样式
&::-webkit-scrollbar {
width: 10px;
}
&::-webkit-scrollbar-thumb {
background-color: #c0d8f3;
border-radius: 6px;
}
&::-webkit-scrollbar-track {
background-color: transparent;
border-radius: 6px;
}
// 用于缩放后截取掉不需要的空白的容器
.pdf-box {
overflow: hidden;
padding: 24px;
// border: 1px solid rgb(165, 11, 236);
}
// pdf预览区容器
.pdf-scale-box {
box-shadow: 0px 0px 20px 5px #666565;
// border: 2px solid #090;
// 设置缩放的中心点
transform-origin: center top;
transition: .2s;
}
}
.bottom-tools {
height: 50px;
line-height: 50px;
background-color: #c0d8f3;
border: 1px solid #5caaf8;
border-radius: 6px;
display: flex;
padding: 0px 24px;
.page {
color: #636a70;
flex-grow: 1;
// border: 1px solid #909;
span {
margin-right: 20px;
}
}
.scale {
// border: 1px solid #909;
text-align: right;
}
}
}
</style>
至此,pdf预览组件就已经愉快的封装完毕。在需要的地方将本组件引入并传入获取到的pdf预览地址,同时按需给本组件引入到的外层容器设置高度,即可实现pdf的翻页预览、缩放效果。
今天的文章vue页面显示pdf_vue预览pdf文件流分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/81954.html