使用pdf.js插件在线打开pdf
天记录一个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文件到页面:
<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>
最后上一下效果展示截图:
- 孙明俊:人工智能之算力演进
- 探秘Tomcat——一个简易的Servlet容器
- 2017年与机器学习相关的10大Python开源库
- 控制并发访问的三道屏障: WCF限流(Throttling)体系探秘[上篇]
- 探秘Tomcat——从一个简陋的Web服务器开始
- EnterLib PIAB又一个BUG?[续]——这是一个致命的BUG
- Google工程师:谷歌翻译在几个月内效果明显提升的秘诀
- 回调与并发: 通过实例剖析WCF基于ConcurrencyMode.Reentrant模式下的并发控制机制
- EnterLib PIAB又一个BUG?[续]——这是一个致命的BUG
- 年终盘点2017年发生在上海的科技大新闻
- 数字供应链第六章-网络风险、知识产权盗窃、合规和数据挖掘业务合同
- 使命必达: 深入剖析WCF的可靠会话[实例篇](内含美女图片,定力差者慎入)
- 快速全面构建大数据认知体系
- 谈谈分布式事务之二:基于DTC的分布式事务管理模型[上篇]
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Kubernetes 无状态应用的一般特征
- 一段简单的代码,能让所有GIF图实现时光倒流
- 你喜欢的女主播颜值多少分,今天带你测试虎牙直播女主播的颜值
- (译)kubectl 的奇技淫巧
- Python实现主播人气排行榜,带你发现人气王
- (译)Kubernetes:移除 CPU 限制,服务运行更快
- python_不误正业之贪吃蛇
- 如何让你在众多二手车中挑中满意的?python帮你实现(附源码)
- python苦短_SVM测试
- 招聘信息太多,哪家职位才是适合你的?Python采集招聘信息
- 福利来啦,送给大家一个小游戏的源码,不要错过哟(复制粘贴运行即可玩)
- 今天抠图,Python实现一键换底片!想换什么换什么(附源码)
- 你想不到的沙雕,8行代码Python实现GIF图倒放,每天的快乐源泉
- python爬虫-首医
- 2万8千张图片如何用python组成一张(简洁明了附源码)