有这么一个需求,要求打开pdf文件实现预览,分页跳转、搜索关键字。期望效果如下:
经过一番调研选择使用pdfjs-dist来完成这一功能。
第一种方案:使用npm在项目中安装pdfjs-dist
npm install pdfjs-dist
执行安装文件报错了,应该是node版本不兼容,到https://www.npmjs.com/上找往期版本,查了一些评论,评价2.16.105版本兼容性好,安装试一下。
npm i pdfjs-dist@2.16.105
在代码中引入
<template><Modalv-model="visible"fullscreenfooter-hide@on-cancel="cancel"><div id="pdf-view"><canvas v-for="page in state.pdfPages" :key="page" id="pdfCanvas" /><div id="text-view"></div></div></Modal>
</template>
<script>import * as pdfjsViewer from 'pdfjs-dist/web/pdf_viewer.js'import 'pdfjs-dist/web/pdf_viewer.css'import * as PDF from 'pdfjs-dist'PDF.GlobalWorkerOptions.workerSrc = '/pdf.worker.js'const pdf = 'http://www.nhc.gov.cn/sps/s7887k/202301/0e55a01df50c47d9a4a43db026e3afc3/files/63f752a17cfd4b4781f744477561866f.pdf'let pdfDoc = null;export default {data () {return {state: {// 文件路径pdfPath: pdf,// 总页数pdfPages: 1, // 页面缩放pdfScale: 1, },visible: false,}},mounted () {// this.loadFile(this.state.pdfPath)},methods: {init () {this.visible = truethis.loadFile(this.state.pdfPath)},cancel () {this.visible = false},loadFile(url) {PDF.getDocument({url,cMapUrl: 'https://cdn.jsdelivr.net/npm/pdfjs-dist@2.16.105/cmaps/',cMapPacked: true,}).promise.then((pdf) => {pdfDoc = pdf// 获取pdf文件总页数this.state.pdfPages = pdf.numPagesthis.$nextTick(() => {this.renderPage(1) // 从第一页开始渲染})})},renderPage(num) {pdfDoc.getPage(num).then((page) => {const canvas = document.getElementById('pdfCanvas')const ctx = canvas.getContext('2d')const viewport = page.getViewport({ scale: this.state.pdfScale })canvas.width = viewport.widthcanvas.height = viewport.heightconst renderContext = {canvasContext: ctx,viewport}page.render(renderContext)})}}}
</script>
引入的过程中发生了报错
原因是需要在引入 pdf is-dist 之后配置 workerSrc,但是引入 pdf is-dist/bui1d/pdf. worker.entry之后浏览器还是有个警告:Warning;Settingup fake worker.,几方查找原来是pdf.workerjs必须位于自己的文件中(而不是与pdfjs捆绑在起)。否则它不能在服务工作线程中运行。
解决方式:将 pdfis-dist/bui1d/pdf.worker.is 复制一份放到项目 public 目录下
能够预览但是不是想要的效果,貌似这种只能实现pdf预览功能,而我想要的是官方演示的那种带各种操作的效果。
第二种方法:直接将预构建版本放入public文件夹下使用viewer.html
下载,解压到public文件夹下。
使用
// 直接在新窗口中打开
window.open(`/pdfjs-2.5.207-dist/web/viewer.html?file=${pdfurl}`, '_blank')
找到pdfjs-2.5.207-dist/web/wiewer.js
效果如下,有个bug,打开pdf文件以后,分页数字会被缓存,下次再打开,会停留在这个页面,如果想回到第1页,需要做一下处理。
上面这个方法只能禁用本地对跨域的检查,如果引用的pdf文件地址是外链,依然会报跨域问题,如果对pdf的来源不能确定是不太好解决的。
上面这种跨域限制,就需要后端介入处理了。
如果产品只是要预览pdf文件,可以用第一种方法或者在新窗口打开pdf文件查看。
window.open(pdfurl, '_blank')
在浏览器的新窗口打开查看pdf文件,没有跨域问题,遗憾的是显示效果不能控制。先记到这儿吧,后期如果有更好的解决跨域方案再来更新。
参考链接
- https://blog.csdn.net/weixin_44104341/article/details/119821699?spm=1001.2014.3001.5506
- vue3项目使用pdf.js插件实现:搜索高亮、修改pdf.js显示的页码、向pdf.js传值、控制搜索、处理接口文件流
- 002-Vue项目中通过pdfjs实现PDF预览