使用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 相关文章推荐
jQuery 1.4 15个你应该知道的新特性(译)
Jan 24 Javascript
jquery序列化表单以及回调函数的使用示例
Jul 02 Javascript
jQuery获得包含margin的outerWidth和outerHeight的方法
Mar 25 Javascript
判断JS对象是否拥有某属性的方法推荐
May 12 Javascript
JS面试题---关于算法台阶的问题
Jul 26 Javascript
利用AngularJs实现京东首页轮播图效果
Sep 08 Javascript
vue2.0 兄弟组件(平级)通讯的实现代码
Jan 15 Javascript
解决vue 中 echart 在子组件中只显示一次的问题
Aug 07 Javascript
详解React之key的使用和实践
Sep 29 Javascript
vue 之 css module的使用方法
Dec 04 Javascript
JavaScript创建对象的四种常用模式实例分析
Jan 11 Javascript
vue下axios拦截器token刷新机制的实例代码
Jan 17 Javascript
详解如何在Canvas中添加事件的方法
Apr 17 #Javascript
Canvas三种动态画圆实现方法说明(小结)
如何在CocosCreator里画个炫酷的雷达图
jquery插件实现图片悬浮
详解CocosCreator消息分发机制
Apr 16 #Javascript
CocosCreator入门教程之网络通信
Apr 16 #Javascript
JavaScript嵌入百度地图API的最详细方法
You might like
php自动获取字符串编码函数mb_detect_encoding
2011/05/31 PHP
PHP daddslashes 使用方法介绍
2012/10/26 PHP
PHP之生成GIF动画的实现方法
2013/06/07 PHP
php修改指定文件后缀的方法
2014/09/11 PHP
CI框架入门示例之数据库取数据完整实现方法
2014/11/05 PHP
laravel-admin select框默认选中的方法
2019/10/03 PHP
使用js正则控制input标签只允许输入的值
2013/07/29 Javascript
javascript中全局对象的isNaN()方法使用介绍
2013/12/19 Javascript
多引号嵌套的变量命名的问题
2014/05/09 Javascript
nodejs命令行参数处理模块commander使用实例
2014/09/17 NodeJs
浅谈jQuery中的事件
2015/03/23 Javascript
究竟什么是Node.js?Node.js有什么好处?
2015/05/29 Javascript
JavaScript SHA512&amp;SHA256加密算法详解
2015/08/11 Javascript
Winform客户端向web地址传参接收参数的方法
2016/05/17 Javascript
浅谈jQuery绑定事件会叠加的解决方法和心得总结
2016/10/26 Javascript
详解Angular.js数据绑定时自动转义html标签及内容
2017/03/30 Javascript
判断滚动条滑到底部触发事件(实例讲解)
2017/11/15 Javascript
vue transition 在子组件中失效的解决
2019/11/12 Javascript
jquery实现聊天机器人
2020/02/08 jQuery
vant实现购物车功能
2020/06/29 Javascript
vue 子组件watch监听不到prop的解决
2020/08/09 Javascript
js实现详情页放大镜效果
2020/10/28 Javascript
JavaScript构造函数原理及实现流程解析
2020/11/19 Javascript
原生js 实现表单验证功能
2021/02/08 Javascript
python函数局部变量用法实例分析
2015/08/04 Python
python虚拟环境virualenv的安装与使用
2016/12/18 Python
Python字典操作详细介绍及字典内建方法分享
2018/01/04 Python
python求质数的3种方法
2018/09/28 Python
Python实现简易过滤删除数字的方法小结
2019/01/09 Python
Python龙贝格法求积分实例
2020/02/29 Python
使用CSS3制作饼状旋转载入效果的实例
2015/06/23 HTML / CSS
英国领先的运动物理治疗供应公司:Vivomed
2018/07/14 全球购物
先进党支部事迹材料
2014/01/13 职场文书
家长会学生演讲稿
2014/04/26 职场文书
残疾人小组计划书
2014/04/27 职场文书
小学班主任工作随笔
2015/08/15 职场文书