使用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 相关文章推荐
求得div 下 img的src地址的js代码
Feb 28 Javascript
侧栏跟随滚动的简单实现代码
Mar 18 Javascript
选择器中含有空格在使用示例及注意事项
Jul 31 Javascript
jquery操作select详解(取值,设置选中)
Feb 07 Javascript
js 金额格式化来回转换示例
Feb 23 Javascript
JS使用正则表达式除去字符串中重复字符的方法
Nov 05 Javascript
JS弹窗 JS弹出DIV并使整个页面背景变暗功能的实现代码
Apr 21 Javascript
vue+iview+less 实现换肤功能
Aug 17 Javascript
VeeValidate 的使用场景以及配置详解
Jan 11 Javascript
Vue多环境代理配置方法思路详解
Jun 21 Javascript
微信小程序学习总结(二)样式、属性、模板操作分析
Jun 04 Javascript
js不常见操作运算符总结
Nov 20 Javascript
详解如何在Canvas中添加事件的方法
Apr 17 #Javascript
Canvas三种动态画圆实现方法说明(小结)
如何在CocosCreator里画个炫酷的雷达图
jquery插件实现图片悬浮
详解CocosCreator消息分发机制
Apr 16 #Javascript
CocosCreator入门教程之网络通信
Apr 16 #Javascript
JavaScript嵌入百度地图API的最详细方法
You might like
BBS(php &amp; mysql)完整版(三)
2006/10/09 PHP
解析PHP中$_FILES的使用以及注意事项
2013/07/05 PHP
thinkphp多表查询两表有重复相同字段的完美解决方法
2016/09/22 PHP
深入浅析PHP的session反序列化漏洞问题
2017/06/15 PHP
CodeIgniter框架数据库基本操作示例
2018/05/24 PHP
thinkphp5.1 文件引入路径问题及注意事项
2018/06/13 PHP
jquery中eq和get的区别与使用方法
2011/04/14 Javascript
Javascript执行效率全面总结
2013/11/04 Javascript
javascript的parseFloat()方法精度问题探讨
2013/11/26 Javascript
js如何判断用户是否是用微信浏览器
2014/06/05 Javascript
PHP+jQuery+Ajax实现多图片上传效果
2015/03/14 Javascript
AngualrJS中每次$http请求时的一个遮罩层Directive
2016/01/26 Javascript
超实用的JavaScript表单代码段
2016/02/26 Javascript
jQuery简单创建节点的方法
2016/09/09 Javascript
Angularjs中三种数据的绑定策略(“@”,“=”,“&amp;”)
2016/12/23 Javascript
Swiper自定义分页器使用详解
2017/12/28 Javascript
这样回答继承可能面试官更满意
2019/12/10 Javascript
JS变量提升原理与用法实例浅析
2020/05/22 Javascript
解决Element中el-date-picker组件不回填的情况
2020/11/07 Javascript
[02:49]2018DOTA2亚洲邀请赛主赛事决赛日战况回顾 Mineski鏖战5局夺得辉耀
2018/04/10 DOTA
Python爬虫框架Scrapy安装使用步骤
2014/04/01 Python
MySQLdb ImportError: libmysqlclient.so.18解决方法
2014/08/21 Python
python基础之包的导入和__init__.py的介绍
2018/01/08 Python
Python异常对代码运行性能的影响实例解析
2018/02/08 Python
Python格式化日期时间操作示例
2018/06/28 Python
Python给定一个句子倒序输出单词以及字母的方法
2018/12/20 Python
在Python中表示一个对象的方法
2019/06/25 Python
Python 中 -m 的典型用法、原理解析与发展演变
2019/11/11 Python
Python configparser模块封装及构造配置文件
2020/08/07 Python
Html5 video标签视频的最佳实践
2020/02/26 HTML / CSS
移动端HTML5开发神器之vconsole详解
2020/12/15 HTML / CSS
使用HTML和CSS实现的标签云效果(附demo)
2021/02/03 HTML / CSS
纪检干部先进事迹材料
2014/08/23 职场文书
文秘班元旦晚会活动策划方案
2014/08/28 职场文书
公安忠诚教育心得体会
2016/01/23 职场文书
python使用torch随机初始化参数
2022/03/22 Python