PDF.js Electron Viewer - 掘金

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

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

从零准备项目

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

Electron React

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

bash

复制代码

`# 获取模板
git clone --depth=1 \
https://github.com/electron-react-boilerplate/electron-react-boilerplate \
electron-pdf-viewer
cd electron-pdf-viewer

设定仓库

git remote set-url origin git@github.com:ikuokuo/electron-pdf-viewer.git

如果想合并成一个初始提交

https://stackoverflow.com/a/23486788

git 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`

bash

复制代码

`# 依赖
npm install

运行

npm start

打包

npm run package`

准备编辑器(VSCode):

bash

复制代码

`code --install-extension dbaeumer.vscode-eslint
code --install-extension dzannotti.vscode-babel-coloring
code --install-extension EditorConfig.EditorConfig`

其他编辑器,可见 Editor Configuration

Ant Design

添加 antd 依赖:

bash

复制代码

npm install antd

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

PDF.js

添加 pdfjs 依赖:

bash

复制代码

`npm install pdfjs-dist
npm install -D worker-loader`

此外,准备 PDF 样例进 static/,简单用 Python 提供 HTTP 访问:

bash

复制代码

npm run static

用于开发运行,正式运行可用 file:// 地址。

PDF.js 渲染

使用 API

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

1. 导入包

ts

复制代码

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

2. 渲染页面

ts

复制代码

``(async () => {
// 获取 doc
const loadingTask = pdfjsLib.getDocument(url);
const pdf = await loadingTask.promise;
console.log(PDF loaded, n=${pdf.numPages});
setNumPages(pdf.numPages);
// 获取 page
const page = await pdf.getPage(1);
// 获取 canvas
const 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;
// 渲染 page
const 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. 导入包

ts

复制代码

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

2. 布局页面

html

复制代码

`<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 定位:

scss

复制代码

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

3. 渲染 PDF

ts

复制代码

``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-any
eventBus.on('pagesloaded', (e: any) => {
console.log('pagesloaded');
console.log(e);
setNumPages(e.pagesCount);
});
eventBus.on('pagerendered', () => {
console.log('pagerendered');
});
// 创建 PDFViewer
const 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 嵌入。

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

bash

复制代码

`git clone -b master --depth=1 https://github.com/mozilla/pdf.js.git
cd pdf.js

安装依赖

npm install -g gulp-cli
npm install

开发运行

gulp server

http://localhost:8888/web/viewer.html

编译发布

gulp generic

build/generic/`

iframe 嵌入的话,也是打开 web/viewer.html?file=x.pdf

html

复制代码

``<div className="viewerHTML">
<div>pdfUrl={pdfUrl}</div>
<div>pdfWebViewerUrl={pdfWebViewerUrl}</div>
<iframe
className="pdfViewer"
title="PdfViewerHTML"
src={${pdfWebViewerUrl}?file=${pdfUrl}}
/>
</div>``

scss

复制代码

`.viewerHTML {
.pdfViewer {
border: none;
width: 100%;
height: 100%;
}
}`

这里打开的 npm run static 提供的 HTTP 地址,效果如下:

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

最后

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

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

原网址: 访问
创建于: 2023-08-18 14:52:58
目录: default
标签: 无

请先后发表评论
  • 最新评论
  • 总共0条评论