公司最近新做了一个小程序其中有个需求是预览 PDF, 在 小程序 里面
这里我大概想到了三种方法,各有优缺点
小程序直接打开
- 优点:方便快捷,调用就能使用
- 缺点:只能预览,无法做其他操作
API:新开页面打开文档
wx.downloadFile({
// 示例 url,并非真实存在
url: 'http://example.com/somefile.pdf',
success: function (res) {
const filePath = res.tempFilePath
wx.openDocument({
filePath: filePath,
success: function (res) {
console.log('打开文档成功')
}
})
}
})
pdfjs 预览
- 优点:可以 按需加载,并且有 工具栏,目录等等,可以 指定页码
- 缺点:源码体积过大,并且有很多功能用不上,并且不支持双指缩放
官网:pdfjs
下载好后直接放进 static 文件,使用 /static/pdfjs-new/web/viewer.html?file=, file 后跟的就是你的文件。
<iframe class="iframe" :src="src"></iframe>
let path = '/static/pdfjs-new/web/viewer.html?file='
let src = path + encodeURIComponent(在线链接)
如果你的是 在线链接,请使用 encodeURIComponent 去转义,如果不是,就不用转义
以下处理均在 web\viewer.js 中
1. 处理跨域
注释掉下面这段代码
if (origin !== viewerOrigin && protocol !== "blob:") {
throw new Error("file origin does not match viewer's");
}
2. 打开按需加载
因为 pdfjs 默认是全部加载,找到 disableAutoFetch 这个属性,修改为 true,
3. 指定页码
这里我的处理有点极端,大概处理过程是,因为获取地址栏参数,如果地址栏有 page 这个字段,那我就拿到这个参数,去指定页码,可以跑通,但是肯定不是最优解。
找到这个方法 setInitialView 在最后面加上下面代码
let url = new URL(window.location.href);
url = decodeURIComponent(url)
url = new URL(url);
const page = url.searchParams.get('page')
if(page) this.pdfViewer.currentPageNumber = parseInt(page)
vue-pdf-embed插件
- 优点:传入链接就能用,可以指定页码
- 缺点:没有目录,没有工具栏,不支持缩放
下载
$ yarn add vue-pdf-embed
使用
import VuePdfEmbed from 'vue-pdf-embed';
const state = reactive({
source: '', // 文件地址
pageCount: 1, // 总页数
page: 1,
})
const pdfRef = ref()
function rendered() {
state.pageCount = pdfRef.value.pageCount
}
<vue-pdf-embed ref="pdfRef" :source="state.source"
:page="state.page" @rendered="rendered"/>
page 可以加减,自己写方法,直接修改 state.page 就行
缩放:我这里使用的是 uniapp 的 movable-area 和 movable-view, movable-view 记得宽高百分百