AI智能
改变未来

PDF.js Electron Viewer

PDF.js 是基于 HTML5 解析与渲染 PDF 的 JavaScript 库,由 Mozilla 主导开源。

本文旨在介绍 PDF.js 于 Electron 里如何开始使用,实际尝试了用其 API 或嵌入 HTML 的几种方式。

  • 代码: https://github.com/ikuokuo/electron-pdf-viewer.git

从零准备项目

项目采用 Electron React Antd PDF.js 来实现,以下是从零准备项目的过程。

Electron React

这里用 electron-react-boilerplate 模板开始 Electron React 项目。

# 获取模板git clone --depth=1 \\https://github.com/electron-react-boilerplate/electron-react-boilerplate \\electron-pdf-viewercd electron-pdf-viewer# 设定仓库git remote set-url origin git@github.com:ikuokuo/electron-pdf-viewer.git# 如果想合并成一个初始提交#  https://stackoverflow.com/a/23486788git config --global alias.squash-all \'!f(){ git reset $(git commit-tree HEAD^{tree} -m "${1:-A new start}");};f\'git squash-all "first commit"git push -u origin main
# 依赖npm install# 运行npm start# 打包npm run package

准备编辑器(VSCode):

code --install-extension dbaeumer.vscode-eslintcode --install-extension dzannotti.vscode-babel-coloringcode --install-extension EditorConfig.EditorConfig

其他编辑器,可见 Editor Configuration。

Ant Design

添加

antd

依赖:

npm install antd

之后,就可以快速布局页面了,如下:

PDF.js

添加

pdfjs

依赖:

npm install pdfjs-distnpm install -D worker-loader

此外,准备 PDF 样例进

static/

,简单用 Python 提供 HTTP 访问:

npm run static

用于开发运行,正式运行可用

file://

地址。

PDF.js 渲染

使用 API

用 API 渲染页面,可见官方 Examples。

1. 导入包

import * as pdfjsLib from \'pdfjs-dist/webpack\';

2. 渲染页面

(async () => {// 获取 docconst loadingTask = pdfjsLib.getDocument(url);const pdf = await loadingTask.promise;console.log(`PDF loaded, n=${pdf.numPages}`);setNumPages(pdf.numPages);// 获取 pageconst page = await pdf.getPage(1);// 获取 canvasconst scale = 1.5;const viewport = page.getViewport({ scale });// Support HiDPI-screens.const outputScale = window.devicePixelRatio || 1;const canvas = canvasRef.current;if (canvas == null) return;const context = canvas.getContext(\'2d\');canvas.width = Math.floor(viewport.width * outputScale);canvas.height = Math.floor(viewport.height * outputScale);canvas.style.width = `${Math.floor(viewport.width)}px`;canvas.style.height = `${Math.floor(viewport.height)}px`;const transform =outputScale !== 1 ? [outputScale, 0, 0, outputScale, 0, 0] : null;// 渲染 pageconst renderContext = {canvasContext: context,transform,viewport,};await page.render(renderContext);console.log(\'Page rendered!\');})();

完整代码,见 Pdfjs/index.tsx。效果如下:

使用 Viewer API

用 Viewer API 渲染,其在

pdfjs-dist/web/pdf_viewer

路径下。

1. 导入包

import * as pdfjsLib from \'pdfjs-dist/webpack\';import { PDFViewer, EventBus } from \'pdfjs-dist/web/pdf_viewer\';import \'pdfjs-dist/web/pdf_viewer.css\';

2. 布局页面

<div className="viewer"><div>url={url}</div><div>numPages={numPages}</div><div ref={hrRef} /><div ref={containerRef} className="container"><div className="pdfViewer" /></div></div>

要求

absolute

定位:

.viewer {position: relative;.container {position: absolute;top: 0;left: 0;right: 0;bottom: 0;overflow: scroll;}}

3. 渲染 PDF

const container = containerRef.current;if (container == null) return;if (hrRef.current) {container.style.top = `${hrRef.current.offsetTop}px`;}// 监听事件,必须传参 PDFViewer 为实例const eventBus = new EventBus(null);eventBus.on(\'pagesinit\', () => {console.log(\'pagesinit\');});// eslint-disable-next-line @typescript-eslint/no-explicit-anyeventBus.on(\'pagesloaded\', (e: any) => {console.log(\'pagesloaded\');console.log(e);setNumPages(e.pagesCount);});eventBus.on(\'pagerendered\', () => {console.log(\'pagerendered\');});// 创建 PDFViewerconst pdfViewer = new PDFViewer({container,eventBus,linkService: null,renderer: \'canvas\',l10n: null,});// 导入 Document(async () => {const loadingTask = pdfjsLib.getDocument(url);const pdf = await loadingTask.promise;pdfViewer.setDocument(pdf);})();

完整代码,见 PdfViewer/index.tsx。效果如下:

使用 Viewer HTML

PDF.js 提供了在线演示的

viewer.html

,不过

pdfjs-dist

里没有,要自己编译其源码。

编译结果已放进

static/pdfjs/

,可用 Electron Window 打开

web/viewer.html?file=x.pdf

或用

iframe

嵌入。

如果自己重新编译,过程如下:

git clone -b master --depth=1 https://github.com/mozilla/pdf.js.gitcd pdf.js# 安装依赖npm install -g gulp-clinpm install# 开发运行gulp server# http://localhost:8888/web/viewer.html# 编译发布gulp generic# build/generic/

iframe

嵌入的话,也是打开

web/viewer.html?file=x.pdf

<div className="viewerHTML"><div>pdfUrl={pdfUrl}</div><div>pdfWebViewerUrl={pdfWebViewerUrl}</div><iframeclassName="pdfViewer"title="PdfViewerHTML"src={`${pdfWebViewerUrl}?file=${pdfUrl}`}/></div>
.viewerHTML {.pdfViewer {border: none;width: 100%;height: 100%;}}

这里打开的

npm run static

提供的 HTTP 地址,效果如下:

iframe

要打开本地 HTML 试了下没成,如果想在 Electron + React 下这么用,还要研究下怎么弄。

最后

PDF.js 可以说是 Web 渲染 PDF 的不二选择,很多 PDF Web Viewer 库都是基于它实现的。

GoCoding 个人实践的经验分享,可关注公众号!

赞(0) 打赏
未经允许不得转载:爱站程序员基地 » PDF.js Electron Viewer