哈喽大家好啊。前半年还挺忙的,一直也没有发文章,有老哥想我了嘛。这两天发现老有人私信问我 PDF 相关的内容。
那么好,为了我能安心摸鱼,我准备出一篇文章来介绍一下如何使用 PDFJS 。
PDF.js 由 Mozilla 提供支持。目标是创建一个通用的、基于 Web 标准的平台,用于解析和呈现 PDF。
<embed src="https://www.lilnong.top/static/pdf/B-4-RxJS%E5%9C%A8React%E4%B8%AD%E7%9A%84%E5%BA%94%E7%94%A8-%E9%BE%99%E9%80%B8%E6%A5%A0_.pdf">
<iframe src="https://www.lilnong.top/static/pdf/B-4-RxJS%E5%9C%A8React%E4%B8%AD%E7%9A%84%E5%BA%94%E7%94%A8-%E9%BE%99%E9%80%B8%E6%A5%A0_.pdf"></iframe>
浏览器 | 兼容性 | 配图 |
---|---|---|
Chrome(PC)(Mac) | 支持 | |
safari(PC)(Mac) | 支持 | |
Firefox(PC)(Mac) | 支持 | |
Firefox(PC)(Windows) | 支持 | |
Edge(PC)(Windows) | 支持 | |
IE(PC)(Windows) | 不支持 | |
微信(Android)(vivo x27) | 不支持 | |
Chrome(Android)(vivo x27) | 不支持 | |
QQ浏览器(Android)(vivo x27) | 不支持 |
优点:简单,支持大部分 PC 浏览器(IE 不支持)。跨域资源同样可以(无需 cors)
缺点:不支持移动端浏览器,不支持 IE 等低版本浏览器。样式无法自定义。
测试地址,方案兼容性比较好,需要资源同域 或者 cors跨域,可以自定义样式。
自己部署一个 pdfjs-view。 (推荐,更稳定)
/web/viewer-1.html
和 /legacy/web/viewer.html
。legacy 支持低版本浏览器,使用 es5 编写,讲道理采用这个方案,你肯定也是为了兼容所有浏览器。(没有的话,就 gulp generic-legacy
生成一份)使用 CDN 或者官方提供的 pdfjs-view。(不推荐,不稳定,异常CORS)
<iframe src="https://www.lilnong.top/static/project?file=https://www.lilnong.top/static/pdf/B-4-RxJS%E5%9C%A8React%E4%B8%AD%E7%9A%84%E5%BA%94%E7%94%A8-%E9%BE%99%E9%80%B8%E6%A5%A0_.pdf"></iframe>
<iframe src="https://www.lilnong.top/static/project/pdfjs-es5-2.5.207/web/viewer-1.html?file=https://www.lilnong.top/static/pdf/B-4-RxJS%E5%9C%A8React%E4%B8%AD%E7%9A%84%E5%BA%94%E7%94%A8-%E9%BE%99%E9%80%B8%E6%A5%A0_.pdf"></iframe>
浏览器 | 兼容性 | 兼容性 ES5 版本 | 配图 |
---|---|---|---|
Chrome(PC)(Mac) | 支持 | 支持 | |
safari(PC)(Mac) | 支持 | 支持 | |
Firefox(PC)(Mac) | 支持 | 支持 | |
Firefox(PC)(Windows) | 支持 | 支持 | |
Edge(PC)(Windows) | 支持 | 支持 | |
IE(PC)(Windows) | 不支持 | 支持 | |
微信(Android)(vivo x27) | 支持 | 支持 | |
Chrome(Android)(vivo x27) | 支持 | 支持 | |
QQ浏览器(Android)(vivo x27) | 支持 | 支持 |
同上,可以看到 IE 都支持,移动端也 OK。
优点:支持大部分浏览器(PC、M端都支持)。跨域资源需要 cors。样式可以自定义。
缺点:需要部署一个 view。
测试地址,方案比较复杂,需要自己实现一套预览配套的内容(分页、放大缩小)。
(function() {
let el = document.getElementById('canvasWrap');
if (!el) {
el = document.createElement('div')
el.id = 'canvasWrap'
document.body.appendChild(el)
}
el.innerHTML = ''
let winW = document.documentElement.clientWidth
// 加载 pdf 资源
let loadingTask = pdfjsLib.getDocument('https://www.lilnong.top/static/pdf/B-4-RxJS%E5%9C%A8React%E4%B8%AD%E7%9A%84%E5%BA%94%E7%94%A8-%E9%BE%99%E9%80%B8%E6%A5%A0_.pdf')
// PDF 加载完成的回调。
loadingTask.promise.then(function(pdf) {
console.log('pdf', pdf)
// 可以获取到总页数。
let pageNum = pdf.numPages
var _pageNum = 1;
var renderPageToCanvas = function(pageNum, auto=false) {
// 获取其中的一个页面
pdf.getPage(pageNum).then(function(page) {
// you can now use *page* here
_pageNum = pageNum
// 获取原始大小的数据
var viewport = page.getViewport({
scale: 1,
});
var scale = (500 / viewport.width).toFixed(2)
viewport = page.getViewport({
scale: scale
});
var canvas = document.createElement('canvas');
el.appendChild(canvas)
var context = canvas.getContext('2d');
canvas.height = viewport.height;
canvas.width = viewport.width;
// 创建了一个canvas画板用来存放
var renderContext = {
canvasContext: context,
viewport: viewport
};
page.render(renderContext);
if (auto)
renderPageToCanvas(pageNum + 1, auto);
});
}
renderPageToCanvas(_pageNum, true);
canvasPrev.onclick = function() {
renderPageToCanvas(Math.max(_pageNum - 1, 1));
}
canvasNext.onclick = function() {
renderPageToCanvas(Math.min(_pageNum + 1, pdf.numPages));
}
}, function(reason) {
console.error(reason)
})
}
)()
浏览器 | 兼容性 | 配图 |
---|---|---|
Chrome(PC)(Mac) | 支持 | |
safari(PC)(Mac) | 支持 | |
Firefox(PC)(Mac) | 支持 | |
Firefox(PC)(Windows) | 支持 | |
Edge(PC)(Windows) | 支持 | |
IE(PC)(Windows) | 不支持 | |
微信(Android)(vivo x27) | 支持 | |
Chrome(Android)(vivo x27) | 支持 | |
QQ浏览器(Android)(vivo x27) | 支持 |
兼容性也还可以,需要依赖canvas。
直接打开
通过上面的内容我们可以实现前端预览PDF功能了,我们来总结一下各个方案的特征。
方案 | 移动端 | PC端(高版本浏览器) | PC端(IE、低版本浏览器) | 跨域 | 复制内容 | 自定义样式(分页、下载等等) |
---|---|---|---|---|---|---|
iframe | ?(平台不支持) | ? | ?(平台不支持) | ? | ? | ? |
embed | ?(平台不支持) | ? | ?(平台不支持) | ?(CORS) | ? | ? |
pdfjs-view | ? | ? | ?(ES6 新特性) | ?(CORS) | ? | ?(基于原有基础去修改) |
pdfjs-view-es5 | ? | ? | ? | ?(CORS) | ? | ?(基于原有基础去修改) |
pdfjs-canvas | ? | ? | ?(canvas) | ?(CORS) | ?(canvas) | ?(完全需要自己去实现一整套操作) |
好了,还需要什么内容欢迎留言啊。我给更新到里面。
data URI scheme 允许我们使用内联(inline-code)的方式在网页中包含数据,可以...
复制代码 代码如下: !DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional...
简介: 企业上云多账号架构中,如何做到从上到下管理的同时,处理好员工的权限边...
1.HTML5的内容类型 内容类型 描述 内嵌 向文档中添加其他类型的内容,例如audio...
注释1:上图整个大背景是这个网页的全部尺寸,中间的小框才是浏览器中的可见尺寸...
content属性一般用于::before、::after伪元素中,用于呈现伪元素的内容。平时con...
Redis 官方在 2020 年 5 月正式推出 6.0 版本,提供很多振奋人心的新特性,所以...
John Au-Yeung 来源:medium 译者:前端小智 有梦想,有干货,微信搜索 【大迁世...
先点赞再看,养成好习惯 前言 这两天在另一个社区看到了一个关于 Tomcat 的提问...
解决方法如下: 第一种 使用iframe,但是目前使用iframe的人已经越来越少了,而...