背景
安卓端微信浏览器无法实现 PDF 在线预览,搜索引擎的结果也不太理想,结合了几篇文章,终于实现了需求。废话不多说,手摸手教你如何使用pdf.js
实现 PDF 在线预览。
准备工作
首先到 pdf.js官网 下载官方提供的 demo。不同版本文件可能有略微差别,我下载的是v2.13.216
,v2.13.216 github 下载链接。解压后的目录是这样的:
修改源码
这个 demo 实现了本地文件的预览,但是不支持跨域文件加载。我的需求是预览远端的 PDF,所以需要做一些处理。
打开 web 目录下的viewer.js
修改默认加载文件参数
修改defaultUrl
参数,这个参数是指定默认加载的文档地址,直接修改为空字符串。同目录下的示例 PDF 文件也可以删掉了。
解除跨域限制
在文件的 2160 行左右,注释掉框选的这几行即可。
在项目中使用
在 Vue 项目中使用
- 将整个目录移动到
public
文件夹下
- 新建
PdfViewer.vue
,在 Vue 文件中使用iframe
引用,通过prop
传递 PDF 地址
<template>
<iframe
width="100%"
height="500"
scrolling="no"
:src="`/pdf/web/viewer.html?file=${url}`"
></iframe>
</template>
<script>
export default ({
props: {
url: {
type: String,
required: true
}
},
})
</script>
- 使用时,直接通过
prop
传值
<template>
<div>
<p @click="viewPDF">预览PDF</p>
<pdf-viewer :url="url"></pdf-viewer>
</div>
</template>
<script>
import PdfViewer from './PdfViewer.vue';
export default {
components: {
PdfViewer
},
data: function() {
return {
url: '',
}
},
methods: {
viewPDF: function() {
this.url = 'https://mozilla.github.io/pdf.js/web/compressed.tracemonkey-pldi-09.pdf'
},
}
}
</script>
- 如果没有半屏展示的需求,也可以在需要浏览 PDF 时直接将页面跳转到
viewer.html
,像这样:
viewPDF: function () {
window.location.href = [项目前端地址] + '/pdf/web/viewer.html?file=远端PDF地址'
}
- 效果展示
在 React 项目中使用
在 React 项目中使用和 Vue 差不多,一样的道理,这里我用的是create-react-app
搭起来的demo。
- 将整个目录移动到
public
文件夹下
- 新建
PDFViewer.js
,也是使用iframe
进行引用
function PDFViewer({ file }) {
return (
<iframe width='100%' height='500' scrolling='no'
src={`/pdf/web/viewer.html?file=${file}`}></iframe>
)
}
export default PDFViewer;
- 使用时和 Vue 一样,通过
prop
传值
<PDFViewer file={'https://mozilla.github.io/pdf.js/web/compressed.tracemonkey-pldi-09.pdf'} />
- 直接通过地址跳转的和 Vue 一样,就不再赘述了,直接看效果吧
移动端适配
看到有的文章还在解决移动端手势放大缩小的需求,感觉是伪需求,因为pdf.js
的 demo 中已经做了放大和缩小的功能,只不过不明显。
将web/viewer.css
末尾的几行代码注释掉,就会展示缩放比例的文字了,这样用户就可以意识到这里是可以调整比例的(产品经理把刀放下…)。
优化
在未经优化的情况下,光是pdf.js
和pdf.worker.js
两个核心文件大小加起来有将近2.5MB
,对于移动端来说很影响访问体验。
将这两个文件都替换为压缩后的产物,再配合服务端nginx
的gzip
压缩,实际只需要传输不到350KB
的资源,可以大大降低网络占用,Nice!
- 首先下载 min 版的构建产物,我这个链接指向的是
2.13.216
版的,其他版本可以去 bootcdn 网站搜索。
- 打开
web/viewer.html
,将引入的文件改为 min 版。
- 打开
web/viewer.js
,找到workerSrc
参数,将加载的 worker 改为 min 版。
大功告成
参考文章: https://www.freesion.com/article/37741369420/