vue前端使用pdfjs与pdfdist-mergeofd 实现预览pdf并翻页,同时解决预览pdf显示模糊的问题
插件介绍
pdfdist-mergeofd插件的作用可查看这篇文章,同时使用ofdjs和pdfjs遇到的问题,和解决方法——懒加载
该插件主要是为了解决pdfjs和ofdjs同时使用时产生的兼容性问题,用法与pdfjs一致
实现预览pdf
<!-- 使用el-upload获取上传的文件 --><el-uploadref="upload"action:accept="fileType":on-change="onChangeFile":before-upload="beforeFileUpload":show-file-list="false":auto-upload="false"><el-buttonslot="trigger"type="primary">选择文件</el-button></el-upload><!-- 控制翻页 --><divv-if="pageCount"style="text-align: center"><el-button:disabled="currentPage == 1"@click="clickPre">
上一页
</el-button><span>第{{ currentPage }} / {{ pageCount }}页</span><el-button:disabled="currentPage == pageCount"@click="clickNext">
下一页
</el-button></div><!-- html部分非常简单,创建一个canvas用于后续渲染即可 --><divref="canvasCont"class="canvas-container"><canvasref="myCanvas"class="pdf-container"></canvas></div>
//这里是用的pdfdist-mergeofd,如果使用pdfjs,用法一致import*as pdfJS from'pdfdist-mergeofd'
pdfJS.GlobalWorkerOptions.workerSrc =require('pdfdist-mergeofd/build/pdf.worker.entry')exportdefault{
name:'xxx',data(){return{
file:null,//页面宽度,根据实际调整
pageWidth:800,//页面高度,根据实际调整
pageHeight:1131,//当前页数
currentPage:0,//总页数
pageCount:0,
pdfSrc:null,//尺寸限制
sizeLimit:1*1024*1024,//是否正在渲染页面,防止过快翻页
renderingPage:false,}},
methods:{// 上传文件asynconChangeFile({ raw }){if(!this.beforeFileUpload(raw)){return}if(!raw){return}this.file = raw
if(raw.type ==='application/pdf'){const reader =newFileReader()this.currentType ='pdf'
reader.onload=asynce=>{this.pdfSrc = e.target.result
let data =atob(
reader.result.substring(reader.result.indexOf(',')+1))this.loadPdfData(data)}
reader.readAsDataURL(raw)}},loadPdfData(data){// 引入pdf.js的字体letCMAP_URL='https://unpkg.com/[email protected]/cmaps/'//读取base64的pdf流文件this.pdfData = pdfJS.getDocument({
data: data,
cMapUrl:CMAP_URL,
cMapPacked:true})this.renderPage(1)},// 上一页clickPre(){if(!this.renderingPage &&this.currentPage &&this.currentPage >1){this.renderPage(this.currentPage -1)}}},//下一页clickNext(){if(!this.renderingPage &&this.currentPage &&this.currentPage <this.pageCount
){this.renderPage(this.currentPage +1)}}},// 根据页码渲染相应的PDFrenderPage(num){this.renderingPage =truethis.pdfData.promise.then(pdf=>{this.pageCount = pdf.numPages
pdf.getPage(num).then(page=>{// 获取DOM中为预览PDF准备好的canvasDOM对象let canvas =this.$refs.myCanvas
let ctx = canvas.getContext('2d')// 获取页面比率let ratio = window.devicePixelRatio ||1
console.log(ratio)// 根据页面宽度和视口宽度的比率就是内容区的放大比率let dialogWidth =this.$refs['canvasCont'].offsetWidth
let pageWidth = page.view[2]* ratio
let scale = dialogWidth / pageWidth
let viewport = page.getViewport({ scale: scale *2})
canvas.width = viewport.width * ratio
canvas.height = viewport.height * ratio
// 缩放比率
ctx.setTransform(ratio,0,0, ratio,0,0)let renderContext ={
transform:[1,0,0,1,0,0],
canvasContext: ctx,
viewport: viewport
}
page.render(renderContext).promise.then(()=>{this.renderingPage =falsethis.currentPage = num
})})})},// 计算角度_getRatio(ctx){let dpr = window.devicePixelRatio ||1let bsr =
ctx.webkitBackingStorePixelRatio ||
ctx.mozBackingStorePixelRatio ||
ctx.msBackingStorePixelRatio ||
ctx.oBackingStorePixelRatio ||
ctx.backingStorePixelRatio ||1return dpr / bsr
},beforeFileUpload(file){const fileName = file.name
const fileType =this.fileType.split(',')if(fileType.every(item=>!fileName.endsWith(item))){this.$tip.warning(`请选择格式为${fileType.join('或')}类型的文件`)returnfalse}const{ sizeLimit, sizeLimitWithUnit }=thisif(file.size > sizeLimit){this.$tip.warning(`文件大小不能超过${sizeLimitWithUnit},请重新选择`)returnfalse}returntrue},}}
解决pdf显示模糊
很多文章介绍说调整显示区域大小,这样确实可以提高清晰度,当时当显示区域有限时就无法解决,因此解决方案采用将渲染canvas区域的scale翻倍,同时通过css的transform属性将区域大小设置成原来的一半。
这种方法的原理是增加渲染区域的物理像素数,从而提高图像的分辨率。
参考文章提高PDF预览的清晰度
.pdf-container{transform:scale(0.5);transform-origin: top left;}
效果展示
这是修改之前显示pdf的质量
这是修改之后的质量,变清晰了许多
版权归原作者 剑亦未配妥 所有, 如有侵权,请联系我们删除。