使用PDF.js渲染canvas实现预览pdf的效果示例


Posted in Javascript onApril 17, 2021

一、PDF.js的下载

从官网直接下载即可,地址:http://mozilla.github.io/pdf.js/getting_started/#download

建议下载稳定版本,如下图所示:

使用PDF.js渲染canvas实现预览pdf的效果示例

下载完成后将压缩包解压放在项目下,按照正常引入方式引入即可。

二、使用PDF.js

1.vue使用

第一步安装:

npm install --save pdfjs-dist

第二步引入:

import PDFJS from 'pdfjs-dist'

第三步就是在页面使用即可,下面演示export default中的代码:

export default {
 data () {
  return {
   pdfDoc: null,
   pageNum: 1,
   pageRendering: false,
   pageNumPending: null,
   scale: 0.9
  }
 },
 methods: {
  showPDF (url) {
   let _this = this
   PDFJS.getDocument(url).then(function (pdf) {
    _this.pdfDoc = pdf
    _this.renderPage(1)
   })
  },
  renderPage (num) {
   this.pageRendering = true
   let _this = this
   this.pdfDoc.getPage(num).then(function (page) {
    var viewport = page.getViewport(_this.scale)
    let canvas = document.getElementById('the-canvas')
    canvas.height = viewport.height
    canvas.width = viewport.width

    // Render PDF page into canvas context
    var renderContext = {
     canvasContext: canvas.getContext('2d'),
     viewport: viewport
    }
    var renderTask = page.render(renderContext)
  
    // Wait for rendering to finish
    renderTask.promise.then(function () {
     _this.pageRendering = false
     if (_this.pageNumPending !== null) {
      // New page rendering is pending
      this.renderPage(_this.pageNumPending)
      _this.pageNumPending = null
     }
    })
   })
  },
  queueRenderPage (num) {
   if (this.pageRendering) {
    this.pageNumPending = num
   } else {
    this.renderPage(num)
   }
  },
  onPrevPage () {
   if (this.pageNum <= 1) {
    return
   }
   this.pageNum--
   this.queueRenderPage(this.pageNum)
  },
  onNextPage () {
   if (this.pageNum >= this.pdfDoc.numPages) {
    return
   }
   this.pageNum++
   this.queueRenderPage(this.pageNum)
  }
 }
}

2.HTML(5)使用

第一步正常下载后解压放入项目中;

第二步在项目的页面引入即可,项目结构如下图:

使用PDF.js渲染canvas实现预览pdf的效果示例

由于是公司项目,我将项目名遮住,大家自行取名即可,我在此处将PDF.js放入了js目录下,大家也可以直接放在项目的根目录下。

引入如下代码:

<script type='text/javascript' src='js/PDF.js/build/pdf.js'></script>

第三步即可在js中使用。

① 引入单页的pdf:

var url = sessionStorage.sencondExperience_filePath;
pdfjsLib.workerSrc = 'PDF.js/build/pdf.worker.js';
pdfjsLib.getDocument(url).then(function getPdfHelloWorld(pdf) {
	pdf.getPage(1).then(function getPageHelloWorld(page) {
		var scale = 1;
		var viewport = page.getViewport(scale);
		var canvas = document.getElementById('the-canvas');
		var context = canvas.getContext('2d');
		canvas.height = viewport.height;
		canvas.width = viewport.width;
		var renderContext = {
			canvasContext: context,
			viewport: viewport
		};
		page.render(renderContext);
	});
});

需要注意的是pdfjsLib.workerSrc中,如果换成是PDFJS.workerSrc会报错:PDFJS is notdefined。有博客说在其之前加上PDFJS.disableWorker = true;会避免出错,但我尝试了错误依然存在。使用pdfjsLib.workerSrc不会出错!!!

②引入多页的pdf:

方法一:在html中设置好pdf页数对应的canvas,然后使用js一页一页的去渲染canvas。

html:

<canvas id="the-canvas01"></canvas>
<canvas id="the-canvas02"></canvas>
<canvas id="the-canvas03"></canvas>

js:

var url = sessionStorage.third_filePath;
pdfjsLib.workerSrc = 'PDF.js/build/pdf.worker.js';
pdfjsLib.getDocument(url).then(function getPdfHelloWorld(pdf) {
	pdf.getPage(1).then(function getPageHelloWorld(page) {
		var scale = 1;
		var viewport = page.getViewport(scale);
		var canvas = document.getElementById('the-canvas01');
		var context = canvas.getContext('2d');
		canvas.height = viewport.height;
		canvas.width = viewport.width;
		var renderContext = {
			canvasContext: context,
			viewport: viewport
		};
		page.render(renderContext);
	});
	pdf.getPage(2).then(function getPageHelloWorld(page) {
		var scale = 1;
		var viewport = page.getViewport(scale);
		var canvas = document.getElementById('the-canvas02');
		var context = canvas.getContext('2d');
		canvas.height = viewport.height;
		canvas.width = viewport.width;
		var renderContext = {
			canvasContext: context,
			viewport: viewport
		};
		page.render(renderContext);
	});
	pdf.getPage(3).then(function getPageHelloWorld(page) {
		var scale = 1;
		var viewport = page.getViewport(scale);
		var canvas = document.getElementById('the-canvas03');
		var context = canvas.getContext('2d');
		canvas.height = viewport.height;
		canvas.width = viewport.width;
		var renderContext = {
			canvasContext: context,
			viewport: viewport
		};
		page.render(renderContext);
	});
});

可想而知,这种方法对于页面较少的pdfHIA比较合适,但是若是页数很多或者是不知道pdf的页数的情况,这种方法显然不适合了,由此推荐方法二。

方法二:只需要定义好在需要渲染的位置,再根据pdf的页数去动态渲染canvas。

html

< div id="canvas"></ div>

js

//PDF转成图片
var url = sessionStorage.other_filePath;
pdfjsLib.workerSrc = 'PDF.js/build/pdf.worker.js';
//创建
function createPdfContainer(id, className) {
    var pdfContainer = document.getElementById('canvas');
    var canvasNew = document.createElement('canvas');
    $("canvas").on("click",function() {
		var url = sessionStorage.other_filePath;
		window.open(url);
    })
    canvasNew.id = id;
    canvasNew.className = className;
    pdfContainer.appendChild(canvasNew);
};

//渲染pdf
//建议给定pdf宽度
function renderPDF(pdf, i, id) {
    pdf.getPage(i).then(function (page) {

        var scale = 0.62;
        var viewport = page.getViewport(scale);

        //
        //  准备用于渲染的 canvas 元素
        //

        var canvas = document.getElementById(id);
        var context = canvas.getContext('2d');
        canvas.height = viewport.height;
        canvas.width = document.documentElement.clientWidth;

        //
        // 将 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) {
    pdfjsLib.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(url)

三、报错

1.Uncaught TypeError: Cannot read property ‘getContext’ of null

这个错误是因为在html中需要先写好<canvas>标签,定义好id,不能使用div或其他标签。

在html中:

<canvas id="my-canvas"></canvas>

2.Uncaught (in promise) UnknownErrorException {name: “UnknownErrorException”, message: “Failed to fetch”, details: “UnknownErrorException: Failed to fetch”}

这个意思是未能捕获未知错误。我在此处出错的原因主要是后台给的pdf路径有问题导致的,换一个正确的即可~~

3.Uncaught (in promise) InvalidPDFException {name: “InvalidPDFException”, message: “Invalid PDF structure”}

这个意思是说无效的PDF格式的结构,其实就是代码中渲染pdf时的结构出现错误导致的,我是因为直接对pdf的页数:pdf.numPages循环,再去
渲染在canvas导致出错。错误代码如下:

for(const i in pdf.numPages){
	pdf.getPage(i).then(function getPageHelloWorld(page) {
		var scale = 1;
		var viewport = page.getViewport(scale);
		var id = i > 9 ? 'the-canvas' + i : 'the-canvas0' + i;
		var canvas = document.getElementById(id);
		var context = canvas.getContext('2d');
		canvas.height = viewport.height;
		canvas.width = viewport.width;
		var renderContext = {
			canvasContext: context,
			viewport: viewport
		};
		page.render(renderContext);
	});
}

此时将id打印才明白所有id都为 the-canvas15,出现这个错误主要还是js功底不够扎实导致......所以不能这样简单的循环渲染,正确的解决
方法请看上面的讲解!!!

由此关于PDF.js的使用总结就到这了,有什么问题请留言撒~~

到此这篇关于使用PDF.js渲染canvas实现预览pdf的效果示例的文章就介绍到这了,更多相关PDF.js渲染canvas内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章,希望大家以后多多支持三水点靠木!

 
Javascript 相关文章推荐
js函数使用技巧之 setTimeout(function(){},0)
Feb 09 Javascript
js触发asp.net的Button的Onclick事件应用
Feb 02 Javascript
jquery中的事件处理详细介绍
Jun 24 Javascript
Bootstrap组件系列之福利篇几款好用的组件(推荐二)
Jul 12 Javascript
js表单元素checked、radio被选中的几种方法(详解)
Aug 22 Javascript
浅谈js数据类型判断与数组判断
Aug 29 Javascript
JavaScript数组push方法使用注意事项
Oct 30 Javascript
三种Webpack打包方式(小结)
Sep 19 Javascript
webstorm+vue初始化项目的方法
Oct 18 Javascript
从vue源码看props的用法
Jan 09 Javascript
JavaScript类型相关的常用操作总结
Feb 14 Javascript
详解keep-alive + vuex 让缓存的页面灵活起来
Apr 19 Javascript
详解如何在Canvas中添加事件的方法
Apr 17 #Javascript
Canvas三种动态画圆实现方法说明(小结)
如何在CocosCreator里画个炫酷的雷达图
jquery插件实现图片悬浮
详解CocosCreator消息分发机制
Apr 16 #Javascript
CocosCreator入门教程之网络通信
Apr 16 #Javascript
JavaScript嵌入百度地图API的最详细方法
You might like
层叠菜单的动态生成
2006/10/09 PHP
PHP实现限制IP访问及提交次数的方法详解
2017/07/17 PHP
phpStudy配置多站点多域名方法及遇到的403错误解决方法
2017/10/19 PHP
Js制作简单弹出层DIV在页面居中 中间显示遮罩的具体方法
2013/08/08 Javascript
jquery 设置元素相对于另一个元素的top值(实例代码)
2013/11/06 Javascript
AngularJS  ng-table插件设置排序
2016/09/21 Javascript
手机端实现Bootstrap简单图片轮播效果
2016/10/13 Javascript
原生JS中slice()方法和splice()区别
2017/03/06 Javascript
jQuery+C#实现参数RSA加密传输功能【附jsencrypt.js下载】
2017/06/26 jQuery
AngularJS中使用three.js的实例详解
2017/07/21 Javascript
react-native 完整实现登录功能的示例代码
2017/09/11 Javascript
vue 使用axios 数据请求第三方插件的使用教程详解
2019/07/05 Javascript
uni app仿微信顶部导航条功能
2019/09/17 Javascript
[05:09]2016国际邀请赛中国区预选赛淘汰赛首日精彩回顾
2016/06/29 DOTA
python 字符串转列表 list 出现\ufeff的解决方法
2017/06/22 Python
python 将md5转为16字节的方法
2018/05/29 Python
几行Python代码爬取3000+上市公司的信息
2019/01/24 Python
理想高通滤波实现Python opencv示例
2019/01/30 Python
Pyqt5 实现跳转界面并关闭当前界面的方法
2019/06/19 Python
简单了解Django应用app及分布式路由
2019/07/24 Python
Python如何使用turtle库绘制图形
2020/02/26 Python
python3.6环境下安装freetype库和基本使用方法(推荐)
2020/05/10 Python
python中实现词云图的示例
2020/12/19 Python
HTML5 Video标签的属性、方法和事件汇总介绍
2015/04/24 HTML / CSS
HOTEL INFO英国:搜索全球酒店
2019/08/08 全球购物
JBL美国官方商店:扬声器、耳机等
2019/12/01 全球购物
学院书画协会部门岗位职责
2013/12/01 职场文书
无工作经验者个人求职信范文
2013/12/22 职场文书
师范教师毕业鉴定
2014/01/13 职场文书
幼儿园老师寄语
2014/04/03 职场文书
建筑工地门卫岗位职责
2014/04/30 职场文书
2015年个人实习工作总结
2014/12/12 职场文书
环卫工作个人总结
2015/03/04 职场文书
运动员加油词
2015/07/18 职场文书
团队拓展训练心得体会
2016/01/12 职场文书
合作协议书格式范本
2016/03/21 职场文书