pdf.js插件使用记录,在线打开pdf
天记录一个js库:pdf.js。主要是实现在线打开pdf功能。因为项目需求需要能在线查看pdf文档,所以就研究了一下这个控件。
有些人很好奇,在线打开pdf文档浏览器不是支持吗。是的你说的都是现代浏览器,例如谷歌,360,edg等。
但是很不幸的是我们这个项目是要使用我们最喜欢(很烦)的浏览器ie。所有要想使ie能够在线读取pdf,我就知道两种办法第一种下载acrobat reader插件,第二就是使用js库了。
介绍pdf.js
pdf.js是一个开源的js库。
官网:
源码地址:
下载并解压
我们在选中版本后下载后解压会生成两个文件夹:
这两个文件夹核心文件就是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页面,例子:做的功能比较全面。
简单的来说一下吧,很多人可能下载之后直接打开会报错,其实那是因为出现了两个问题:第一个是没有文件,第二个是知道写文件但是存在跨域。就会产生如下错误:
出现这个问题其实也没事,只要我们引用到项目后就不会出现了。然后是我们在使用的地方打开这个页面并且加上文件即可:
window.location.href = "../../content/js/pdfshow/padjs/web/viewer.html?file=pdftest.pdf";
效果展示:
自己实现分页版:
我们自己实现的话就不需要web文件夹下的东西。你就可以删除了。
自己定义实现说起来也是很简单的,官方上已经给了很多代码示例了。废话我就不说了。我就上一下我的代码吧。
首先引入pdf.js文件到页面:
<script src="~/content/js/pdfshow/padjs/build/pdf.js"></script>
引入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); });
相应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文件:
<script src="~/content/js/pdfshow/padjs/build/pdf.js"></script>
页面布局就可以这样子了:
<div style="width:100%;height:100%;background:#404040"> <div id="pdf-container" style=" width:1000px;margin: 0 auto;"> </div> </div>
然后初始化控件吧:
<script> //引入pdf.js之后 // var url = '../pdftest.pdf'; pdfjs.workersrc = '../../content/js/pdfshow/padjs/build/pdf.worker.js'; window.onload = function () { //创建canvas方法 function createpdfcontainer(id, classname) { var pdfcontainer = document.getelementbyid('pdf-container'); var canvasnew = document.createelement('canvas'); canvasnew.id = id; canvasnew.classname = classname; pdfcontainer.appendchild(canvasnew); }; //渲染pdf function renderpdf(pdf, i, id) { pdf.getpage(i).then(function (page) { //默认设置文档的显示大小 var scale = 1.5; var viewport = page.getviewport(scale); // // 准备用于渲染的 canvas 元素 // var canvas = document.getelementbyid(id); var context = canvas.getcontext('2d'); canvas.height = viewport.height; canvas.width = viewport.width; // // 将 pdf 页面渲染到 canvas 上下文中 // var rendercontext = { canvascontext: context, viewport: viewport }; page.render(rendercontext); }); }; //创建和pdf页数等同的canvas数 function createseriescanvas(num, template) { var id = ''; for (var j = 1; j <= num; j++) { id = template + j; createpdfcontainer(id, 'pdfclass'); } } //读取pdf文件,并加载到页面中 function loadpdf(fileurl) { pdfjs.getdocument(fileurl).then(function (pdf) { //用 promise 获取页面 var id = ''; var idtemplate = 'cw-pdf-'; var pagenum = pdf.numpages; //根据页码创建画布 createseriescanvas(pagenum, idtemplate); //将pdf渲染到画布上去 for (var i = 1; i <= pagenum; i++) { id = idtemplate + i; renderpdf(pdf, i, id); } }); } //启动 loadpdf('../pdftest.pdf'); }; </script>
最后上一下效果展示截图:
上一篇: Tableau连接mongoDB数据库
下一篇: tp5多入口配置