天记录一个js库:pdf.js。主要是实现在线打开pdf功能。因为项目需求需要能在线查看pdf文档,所以就研究了一下这个控件。
有些人很好奇,在线打开pdf文档浏览器不是支持吗。是的你说的都是现代浏览器,例如谷歌,360,edg等。
但是很不幸的是我们这个项目是要使用我们最喜欢(很烦)的浏览器IE。所有要想使IE能够在线读取pdf,我就知道两种办法第一种下载Acrobat Reader插件,第二就是使用js库了。
介绍pdf.js
pdf.js是一个开源的js库。
官网:http://mozilla.github.io/pdf.js/
源码地址:https://github.com/mozilla/pdf.js
下载并解压
我们在http://mozilla.github.io/pdf.js/getting_started/#download选中版本后下载后解压会生成两个文件夹:
这两个文件夹核心文件就是build文件下的js文件,web文件是官方给写好的封装示例,你你可选择使用或者不使用。
├── LICENSE ├── build/ │ ├── pdf.js - 显示层 │ └── pdf.worker.js - 核心层 └── web/ ├── cmaps/ - 字符映射(由核心要求) ├── compressed.tracemonkey-pldi-09.pdf - 测试 pdf ├── debugger.js - 有帮助的PDF调试功能 ├── images/ - 观看者和注释图标的图像 ├── l10n.js - 汉化 ├── locale/ - 翻译文件 ├── viewer.css - viewer 页面样式 ├── viewer.html - viewer 页面 └── viewer.js - viewer js
使用:
使用pdf.js有两种方式:
- 第一种使用官方给写好的示例,简单来说就是上面提到的下载下来的web文件夹。
- 第二种就是自己调用API自己写方法实现,相对于第一种如果自己要的效果不是很多还是自己写。也不是很复杂很容易实现。官方给的代码太多修改维护太麻烦。
使用官方示例:
使用官方示例其实就是使用pdfjs已经写好的viewer.html页面,例子:http://mozilla.github.io/pdf.js/web/viewer.html 做的功能比较全面。
简单的来说一下吧,很多人可能下载之后直接打开会报错,其实那是因为出现了两个问题:第一个是没有文件,第二个是知道写文件但是存在跨域。就会产生如下错误:
出现这个问题其实也没事,只要我们引用到项目后就不会出现了。然后是我们在使用的地方打开这个页面并且加上文件即可:
window.location.href = "../../Content/js/PDFShow/padjs/web/viewer.html?file=pdfTest.pdf";
效果展示:
自己实现分页版:
我们自己实现的话就不需要web文件夹下的东西。你就可以删除了。
自己定义实现说起来也是很简单的,官方上已经给了很多代码示例了。废话我就不说了。我就上一下我的代码吧。
首先引入pdf.js文件到页面:
引入pdf.js之后:
//引入pdf.js之后 var url = '../pdfTest.pdf'; PDFJS.workerSrc = '../../Content/js/PDFShow/padjs/build/pdf.worker.js'; //定义变量 var pdfDoc = null, pageNum = 1, pageRendering = false, pageNumPending = null, scale = 1, canvas = document.getElementById('the-canvas'), ctx = canvas.getContext('2d'); function renderPage(num) { pageRendering = true; pdfDoc.getPage(num).then(function (page) { //设置页面大小 var viewport = page.getViewport(1); console.log(viewport.width); var desiredWidth = "1000"; var scale = desiredWidth / viewport.width; var scaledViewport = page.getViewport(scale); //var viewport = page.getViewport(scale); canvas.height = scaledViewport.height; canvas.width = scaledViewport.width; //设置背景颜色(无效) canvas.style.backgroundColor = "red"; //进行文件读取加载 var renderContext = { canvasContext: ctx, viewport: scaledViewport }; var renderTask = page.render(renderContext); renderTask.promise.then(function () { pageRendering = false; if (pageNumPending !== null) { // New page rendering is pending renderPage(pageNumPending); pageNumPending = null; } }); }); //显示总页数 document.getElementById('page_num').textContent = pageNum; } //翻页方法 function queueRenderPage(num) { if (pageRendering) { pageNumPending = num; } else { renderPage(num); } } function onPrevPage() { if (pageNum <= 1) { return; } pageNum--; queueRenderPage(pageNum); } //上一页监听 document.getElementById('prev').addEventListener('click', onPrevPage); function onNextPage() { if (pageNum >= pdfDoc.numPages) { return; } pageNum++; queueRenderPage(pageNum); } //下一页监听 document.getElementById('next').addEventListener('click', onNextPage); PDFJS.getDocument(url).then(function (pdfDoc_) { pdfDoc = pdfDoc_; document.getElementById('page_count').textContent = pdfDoc.numPages; renderPage(pageNum); });
View Code
相应html代码:
<body style="background:#404040"> <div> <button id="prev">上一页button> <button id="next">下一页button> <span>Page: <span id="page_num">span> / <span id="page_count">span>span> div> <div style="width:100%;height:100%;background:#404040"> <div style=" width:1000px;margin: 0 auto;"> <canvas id="the-canvas">canvas> div> div> body>
效果展示:
自己实现不分页版:
虽然分页很好用,但是确不一定使用所有的场景,比如我就是想一次性打开所有页面然后滚动查看跟读word似的,怎么办,有办法,当然是实现不分页喽,哈哈。
分页好理解啊:根据页数读取然后把读取的内容放到画布上就好了,既然我们明白分页的原理,那么我们稍稍改造一下就是不分页了吗。
不分页:我们全部读出来放到页面不就好了吗,简单来说是这个样,但是具体思路是=》我们先获取到所有页数,然后遍历的把每一页像分页一下放到画布上展示,然后在遍历相同数量画布来对应每页的内容,最后展现出来。
好了大致的思路已经明白了下面就是撸代码:
还是不要忘记引用js文件:
"</span><span style="color: #800000;">~/Content/js/PDFShow/padjs/build/pdf.js</span><span style="color: #800000;">"</span>>
页面布局就可以这样子了:
"width:100%;height:100%;background:#404040">
"pdf-container" style=" width:1000px;margin: 0 auto;">
然后初始化控件吧:
<span style="color: #008000;">//</span><span style="color: #008000;">引入pdf.js之后 </span><span style="color: #008000;">// </span> <span style="color: #0000ff;">var</span> url = <span style="color: #800000;">'</span><span style="color: #800000;">../pdfTest.pdf</span><span style="color: #800000;">'</span><span style="color: #000000;">; PDFJS.workerSrc </span>= <span style="color: #800000;">'</span><span style="color: #800000;">../../Content/js/PDFShow/padjs/build/pdf.worker.js</span><span style="color: #800000;">'</span><span style="color: #000000;">; window.onload </span>=<span style="color: #000000;"> function () { </span><span style="color: #008000;">//</span><span style="color: #008000;">创建canvas方法</span> <span style="color: #000000;"> function createPdfContainer(id, className) { </span><span style="color: #0000ff;">var</span> pdfContainer = document.getElementById(<span style="color: #800000;">'</span><span style="color: #800000;">pdf-container</span><span style="color: #800000;">'</span><span style="color: #000000;">); </span><span style="color: #0000ff;">var</span> canvasNew = document.createElement(<span style="color: #800000;">'</span><span style="color: #800000;">canvas</span><span style="color: #800000;">'</span><span style="color: #000000;">); canvasNew.id </span>=<span style="color: #000000;"> id; canvasNew.className </span>=<span style="color: #000000;"> className; pdfContainer.appendChild(canvasNew); }; </span><span style="color: #008000;">//</span><span style="color: #008000;">渲染pdf</span> <span style="color: #000000;"> function renderPDF(pdf, i, id) { pdf.getPage(i).then(function (page) { </span><span style="color: #008000;">//</span><span style="color: #008000;">默认设置文档的显示大小</span> <span style="color: #0000ff;">var</span> scale = <span style="color: #800080;">1.5</span><span style="color: #000000;">; </span><span style="color: #0000ff;">var</span> viewport =<span style="color: #000000;"> page.getViewport(scale); </span><span style="color: #008000;">//</span> <span style="color: #008000;">//</span><span style="color: #008000;"> 准备用于渲染的 canvas 元素 </span><span style="color: #008000;">// </span> <span style="color: #0000ff;">var</span> canvas =<span style="color: #000000;"> document.getElementById(id); </span><span style="color: #0000ff;">var</span> context = canvas.getContext(<span style="color: #800000;">'</span><span style="color: #800000;">2d</span><span style="color: #800000;">'</span><span style="color: #000000;">); canvas.height </span>=<span style="color: #000000;"> viewport.height; canvas.width </span>=<span style="color: #000000;"> viewport.width; </span><span style="color: #008000;">//</span> <span style="color: #008000;">//</span><span style="color: #008000;"> 将 PDF 页面渲染到 canvas 上下文中 </span><span style="color: #008000;">// </span> <span style="color: #0000ff;">var</span> renderContext =<span style="color: #000000;"> { canvasContext: context, viewport: viewport }; page.render(renderContext); }); }; </span><span style="color: #008000;">//</span><span style="color: #008000;">创建和pdf页数等同的canvas数</span> <span style="color: #000000;"> function createSeriesCanvas(num, template) { </span><span style="color: #0000ff;">var</span> id = <span style="color: #800000;">''</span><span style="color: #000000;">; </span><span style="color: #0000ff;">for</span> (<span style="color: #0000ff;">var</span> j = <span style="color: #800080;">1</span>; j <= num; j++<span style="color: #000000;">) { id </span>= template +<span style="color: #000000;"> j; createPdfContainer(id, </span><span style="color: #800000;">'</span><span style="color: #800000;">pdfClass</span><span style="color: #800000;">'</span><span style="color: #000000;">); } } </span><span style="color: #008000;">//</span><span style="color: #008000;">读取pdf文件,并加载到页面中</span> <span style="color: #000000;"> function loadPDF(fileURL) { PDFJS.getDocument(fileURL).then(function (pdf) { </span><span style="color: #008000;">//</span><span style="color: #008000;">用 promise 获取页面</span> <span style="color: #0000ff;">var</span> id = <span style="color: #800000;">''</span><span style="color: #000000;">; </span><span style="color: #0000ff;">var</span> idTemplate = <span style="color: #800000;">'</span><span style="color: #800000;">cw-pdf-</span><span style="color: #800000;">'</span><span style="color: #000000;">; </span><span style="color: #0000ff;">var</span> pageNum =<span style="color: #000000;"> pdf.numPages; </span><span style="color: #008000;">//</span><span style="color: #008000;">根据页码创建画布</span> <span style="color: #000000;"> createSeriesCanvas(pageNum, idTemplate); </span><span style="color: #008000;">//</span><span style="color: #008000;">将pdf渲染到画布上去</span> <span style="color: #0000ff;">for</span> (<span style="color: #0000ff;">var</span> i = <span style="color: #800080;">1</span>; i <= pageNum; i++<span style="color: #000000;">) { id </span>= idTemplate +<span style="color: #000000;"> i; renderPDF(pdf, i, id); } }); } </span><span style="color: #008000;">//</span><span style="color: #008000;">启动</span> loadPDF(<span style="color: #800000;">'</span><span style="color: #800000;">../pdfTest.pdf</span><span style="color: #800000;">'</span><span style="color: #000000;">); }; </span>
View Code
最后上一下效果展示截图:
作者:YanBigFeg —— 颜秉锋
本文版权归作者和博客园共有,欢迎转载,转载请标明出处。如果您觉得本篇博文对您有所收获,觉得小弟还算用心,请点击右下角的 [推荐],谢谢!