uniapp vue3 pdf预览

1,192 阅读2分钟

公司最近新做了一个小程序其中有个需求是预览 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插件

  • 优点:传入链接就能用,可以指定页码
  • 缺点:没有目录,没有工具栏,不支持缩放

官网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 就行

缩放:我这里使用的是 uniappmovable-areamovable-view, movable-view 记得宽高百分百