使用pdf.js完成pdf浏览

Posted 到点了也

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用pdf.js完成pdf浏览相关的知识,希望对你有一定的参考价值。

需求是要获取当前页和总页数,同时兼容h5和小程序。参考了其他文章,主要记录一下使用过程。
1.下载pdf.js包到本地放到项目中
由于要兼容小程序,包不可过大,所以我放到了服务器上。如果只是H5,那可以直接放在项目中。
官网

2.用web-view渲染

<web-view :src="fileUrl" @message="handlePostMessage" ></web-view>

如果只用h5,可以使用iframe:

 <iframe :src="fileUrl" style="width: 100%; height: 100%; border-width: 0"></iframe>

pdfViewerApplication.pagesCount 获取总页数
pdfViewerApplication.page 获取当前页

3.进行pdf渲染展示

base_url: '/hybrid/html/web/viewer.html',
this.fileUrl = `$base_url?file=$encodeURIComponent(url)` ;

如果pdf.js包放在本地,base_url路径为pdf.js所在路径,不要错了;如果放在服务器,路径是大致这样’http://xxxx:8080/static/hybrid/web/viewer.html’
此时pdf就可以正常显示了

4.根据需求修改源码
修改源码是因为为了实现初始化指定页数、获取当前页数、获取总页数,暂时找不到更好的方法。

(1)在viewer.js文件中找到setInitialView方法,加上这一段代码

          var c_url=window.location.href;
	        //获取参数
	        if(c_url.indexOf("&")&&c_url.indexOf("="))undefined
	            var c_urlArray=
	            var c_val=c_url.split('?')[1];
	            var c_valArray=c_val.split('&');
	            for(let i=0;i<c_valArray.length;i++)undefined
	                let c_key=c_valArray[i].split('=')[0];
	                let c_value=c_valArray[i].split('=')[1];
	                c_urlArray[c_key]=c_value;
	            
	            //跳转至指定页码
	            if(c_urlArray['page'])undefined
	                document.getElementById('pageNumber').value = c_urlArray['page']*1;
	                this.pdfViewer.currentPageNumber = c_urlArray['page']*1;
	              console.log(this.pdfViewer.currentPageNumber,'this.pdfViewer.currentPageNumber==')
	            
	        

在使用时,拼接上页数就可实现。

this.fileUrl = `$baseUrl?file=$encodeURIComponent(url)&page=` + this.currentPage;

(2)在viewer.html中引入相关包(为了实现外部html和uniapp进行通信)

<!-- 微信 JS-SDK 如果不需要兼容小程序,则无需引用此 JS 文件。 -->
	<script type="text/javascript" src="//res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>  
	<!-- uni 的 SDK,必须引用。 -->  
	<script type="text/javascript" src="https://js.cdn.aliyun.dcloud.net.cn/dev/uni-app/uni.webview.1.5.2.js"></script>

关于uni 的 SDK,我试过直接复制别人的包,都无效,后来才知道是版本太旧了不行。

在viewer.js的_createClass中添加相关代码

let arr=this.database.files.slice(-1)
let data=[totalPage:window.PDFViewerApplication.pagesCount,page:arr[0].page]
				// uni.webView.getEnv(function(res) 
				//         console.log('当前环境:' + JSON.stringify(res));
				//       );
					   uni.postMessage(
									data:data
					              );

浏览过多个pdf后,this.database.files会有多个值,所以需要进行筛选,总是取最后一个数据。

使用uni.postMessage进行传出信息,把需要的值放data里。
(3)修改使用的vue的页面代码,需要区分微信小程序和h5

mounted() 
		// #ifdef H5
		window.addEventListener("message", this.ReceiveMessage);
		// #endif
	,

 //h5
	ReceiveMessage(event) 
			if (event.data && event.data.data && event.data.data.arg) 
				this.totalPage = event.data.data.arg[0].totalPage
				this.currentReadPage = event.data.data.arg[1].page + 1
			
		,

微信小程序,通过@message

<web-view :src="fileUrl" @message="handlePostMessage" ></web-view>  
	handlePostMessage(data) 
				let arr=data.detail.data.pop()
				this.totalPage=arr[0].totalPage       //总页数
				this.currentReadPage=arr[1].page   //当前页数
			,

需要注意的是:@message对h5不支持,且只会在特定时机(后退、组件销毁、分享)触发并收到消息,所以我只在返回时获取到页数并传给接口。
实际上如果pdf.js包放在本地,存储空间中会有当前页数

但由于我为了缩减空间放在服务器上所以获取不到,这种方法也就不可取了。

以上是关于使用pdf.js完成pdf浏览的主要内容,如果未能解决你的问题,请参考以下文章

pdfjs获取渲染结束

通过前端js给远程PDF文件加水印

PDF.js实现个性化PDF渲染(文本复制)

移动端展示pdf(在线打开pdf)

SpringBoot 之 PDF大文件分片加载(后端)

在浏览器中编辑*现有* PDF