PDF.js Electron Viewer
2021-12-15 17:53
525 查看
PDF.js 是基于 HTML5 解析与渲染 PDF 的 JavaScript 库,由 Mozilla 主导开源。
本文旨在介绍 PDF.js 于 Electron 里如何开始使用,实际尝试了用其 API 或嵌入 HTML 的几种方式。
从零准备项目
项目采用 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-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
# 依赖 npm install # 运行 npm start # 打包 npm run package
准备编辑器(VSCode):
code --install-extension dbaeumer.vscode-eslint code --install-extension dzannotti.vscode-babel-coloring code --install-extension EditorConfig.EditorConfig
其他编辑器,可见 Editor Configuration。
Ant Design
添加
antd依赖:
npm install antd
之后,就可以快速布局页面了,如下:
PDF.js
添加
pdfjs依赖:
npm install pdfjs-dist npm 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 () => { // 获取 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. 导入包
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-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嵌入。
如果自己重新编译,过程如下:
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:
<div className="viewerHTML"> <div>pdfUrl={pdfUrl}</div> <div>pdfWebViewerUrl={pdfWebViewerUrl}</div> <iframe className="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 个人实践的经验分享,可关注公众号!
相关文章推荐
- HTML5 pdf viewer pdf.js
- Vue Cli项目使用PDF.js预览pdf无法访问到viewer.html
- pdf.js+Viewer.js 预览PDF附件
- [转]PDF预览插件PDFObject.js
- js生成pdf报表
- ReactJS中加入jspdf
- pdf.js 入门使用指南1-安装篇
- java 实现pdf.js加aspose实现doc转pdf
- viewer.js--一个强大的jQuery图像查看插件
- pdfJS在IE浏览器打印后出现空白部分的解决方法
- pdf.js使用教程
- 网页中adobe PDF显示,js控制pdf页面滚动
- 【解决】jsPDF之长图片生成PDF(分页,失真)
- 使用PDF.js渲染canvas实现预览pdf的效果示例
- js在线预览pdf文件
- Electron学习二:学习Electron和Node.js需要知道的JavaScript知识
- 7 Best jQuery & JavaScript PDF Viewer plugin with examples
- 学习笔记PDF.js专题
- android-pdf-viewer在android studio应用问题说明
- Android pdf viewer在android studio应用问题说明详解