PDFJS 使用问题记录
解决 pdf 预览时不显示签名图片的问题
解决 pdf 预览时不显示签名图片的问题 https://github.com/kekingcn/kkFileView/pull/264/files
签名和验签 sdk
签名和验签 sdk:https://github.com/rootca-id/pkiwebsdk/blob/master/src/pdf.js
No "GlobalWorkerOptions.workerSrc" specified
https://github.com/mozilla/pdf.js/issues/10478
How can I load only one or a few pages at one time? #8897
https://github.com/mozilla/pdf.js/issues/8897
使用方式
参考使用方式:
// 可能是旧版 pdf.js
import * as pdfJS from "pdfjs-dist";
import * as pdfJSWeb from "pdfjs-dist/web/pdf_viewer";
import "pdfjs-dist/web/pdf_viewer.css";
const eventBus = new pdfJSWeb.EventBus();
const doc = await pdfJS.getDocument({
url: activePdf.url,
}).promise;
const page = await doc.getPage(pageNum);
const origViewport = page.getViewport({ scale: 1 });
const scale = wrapperSize.width / origViewport.width;
const viewport = page.getViewport({ scale });
const pageView = new pdfJSWeb.PDFPageView({
container: canvas,
id: pageNum,
scale: 1,
defaultViewport: viewport,
eventBus,
});
pageView.setPdfPage(page);
pageView.draw();需要引入 pdf.worker.js 并且 webpack 的话需要 worker-loader 来处理 worker,Vite 的话是直接支持的。
vite项目中如何导入和使用
使用最新的 pdf-dist 版本是 5.4.530
三种方法加载 worker
import { getDocument, GlobalWorkerOptions } from 'pdfjs-dist'
// 方式一
import PdfjsWorker from 'pdfjs-dist/build/pdf.worker.min.mjs?worker&inline'
GlobalWorkerOptions.workerPort = new PdfjsWorker()
// 方式二
// GlobalWorkerOptions.workerPort = new Worker(
// new URL('pdfjs-dist/build/pdf.worker.min.mjs', import.meta.url),
// {
// type: 'module',
// },
// )
// 方式三
// GlobalWorkerOptions.workerSrc = 'your-path/pdf.worker.mjs'其他使用方式
推荐使用 pdf-dist 包的 web 模块。特别是PDFViewer(里面的setDocument好像可以传容器自动创建和加载PDF,待探索)
实战参考项目
基于 PDFJS-DIST + CANVAS 的 PDF 模板签字盖章定位工具
仓库地址:https://gitee.com/twoke/pdf-template-signature-location
直接使用 sdk
就是直接再官网下载人家弄好的 sdk 包,然后放到public文件夹下面。启动的时候就可以直接使用 viewer.html 来加载 pdf 文件了
一些技巧就是 file 这个 ULR query 参数的问题,如果用.../viewer.html?file=这种方式访问文件的话,后面跟的是一个真实的 url 地址。如果用.../viewer.html#file=这种使用 hash 方式的话,后面跟的是一个 path 路径,就是省略了这个协议、域名和端口号之后的访问这个 pdf 的 URL 的 path。
codepen 中参考项目
常见问题
官方插件问题整理
遇事不决看官方 wiki:https://github.com/mozilla/pdf.js/wiki
分块按需加载 PDF
地址:https://github.com/mozilla/pdf.js/wiki/Frequently-Asked-Questions#range
核心实现方式依靠浏览器支持加上 HTTP 的 Range 请求头,PDF.js会自动将PDF文件分割成多个块,然后请求这些块,最后将这些块组合成完整的PDF文件。
其他问题
Vue3中使用响应式数据绑定pdfDoc会报Cannot read from private field
参考文章:【Vue】vue3.2中使用pdf.js踩坑:Cannot read from private field---pdf.js使用详解
核心解决方式是:pdfDoc.getPage的pdfDoc不要使用响应式写法!!!直接使用let pdfDoc = null来初始化即可。
原因的话简单来说就是Vue3里面用Proxy来实现的数据响应式,而在pdf-dist里面有些步骤会对数据进行拦截校验,拦截到是一个Proxy对象,导致校验不通过。详细原因的话可以看上面这篇文章,