PDF预览插件:pdfjs-dist的使用

6,089 阅读1分钟

1:引入pdfjs-dist

npm i pdfjs-dist@版本号

2:项目中使用

截至2024/10/24,chrome对pdfjs-dist@4版本存在兼容问题

pdfjs-dist@4的使用:

1:将node-module中pdfjs-dist目录(build)复制到项目的public目录下

image.png

2:项目中引用:

import * as pdfjsLib from "../../../public/pdfjs-dist/build1/pdf.mjs";
pdfjsLib.GlobalWorkerOptions.workerSrc = new URL('../../../public/pdfjs-dist/build/pdf.worker.mjs', import.meta.url).toString();
pdfjsLib.GlobalWorkerOptions.workerSrc = '/path/to/pdf.worker.min.js';

其中的路径是相对于当前页面的。如果直接从 node_modules 引用 pdf.js,由于构建工具将 node_modules 中的依赖当作外部库管理,它无法自动处理这些内部资源的路径,导致浏览器无法正确加载 pdf.worker.min.js,从而引发找不到 pdf.js 的错误。

pdfjs-dist@3的使用:

1:第一步同上

2:项目中引用:

import * as pdfjsLib from "pdfjs-dist/build/pdf";
pdfjsLib.GlobalWorkerOptions.workerSrc = new URL('../../../public/pdfjs-dist/build/pdf.worker.js', import.meta.url).toString();

3:Vue2和Vue3使用pdfjs-dist用法上也有区别

在Vue3中获取pdf文档不可使用响应式数据

let pdfDoc = '';
const loadingTask = pdfjsLib.getDocument(props.pdfUrl);
loadingTask.promise.then((pdf) => {
  pdfDoc = pdf; //获取pdf文档流
  pdfPages.value = pdfDoc.numPages; //获取pdf文件的页数
  nextTick(() => {
    renderPage(startPage);
  });
});

具体原因:

  • vue2是通过defineProperty来监听数据的改变和读取,
  • vue3是通过proxy来改变数据的。 但是在pdfjs-dist源码中,做了一个拦截校验,校验内容就是当前传入的参数,是否有obj对象,如果没有的话,直接抛出读不到私有变量错误。在之前老项目中,这样写是没有问题的:在pdfjs-dist拦截校验的时候,是一个MaskXXX(好像叫这个名字)的对象。在vue3中,pdfjs-dist拦截校验的时候,获取到的是一个proxy对象。

正确解法:pdfDoc.getPage的pdfDoc不要使用响应式写法 否则会报错:Cannot read from private field