PDF. Js is a JavaScript library based on HTML5 for parsing and rendering PDF, which is open source led by Mozilla.

This article aims to introduce how PDF.js gets started in Electron, actually trying out several ways to use its API or embed HTML.

  • Code: github.com/ikuokuo/ele…

Prepare projects from zero

The project is implemented by Electron React Antd PDF.js. The following is the process of preparing the project from zero.

Electron React

Here we start the electron React project with the electron- React – Boilerplate template.

# get template
git clone --depth=1 \
https://github.com/electron-react-boilerplate/electron-react-boilerplate \
electron-pdf-viewer

cd electron-pdf-viewer

# Set up warehouse
git remote set-url origin [email protected]:ikuokuo/electron-pdf-viewer.git
# If you want to merge into an initial commit
# 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
Copy the code
# rely on
npm install
# run
npm start
# packaged
npm run package
Copy the code

Ready editor (VSCode) :

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

For other editors, see Editor Configuration.

Ant Design

Add ANTD dependencies:

npm install antd
Copy the code

After that, you can quickly lay out the page as follows:

PDF.js

Add PDFJS dependencies:

npm install pdfjs-dist
npm install -D worker-loader
Copy the code

In addition, prepare the PDF sample as static/, which simply provides HTTP access with Python:

npm run static
Copy the code

For development runs, formal runs available file:// address.

PDF. Js rendering

Use the API

Render the page with the API, see the official Examples.

1. Import packages

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

2. Render the page

(async() = > {/ / get the doc
  const loadingTask = pdfjsLib.getDocument(url);
  const pdf = await loadingTask.promise;

  console.log(`PDF loaded, n=${pdf.numPages}`);
  setNumPages(pdf.numPages);

  / / get the page
  const page = await pdf.getPage(1);

  / / get the 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 = `The ${Math.floor(viewport.width)}px`;
  canvas.style.height = `The ${Math.floor(viewport.height)}px`;

  consttransform = outputScale ! = =1 ? [outputScale, 0.0, outputScale, 0.0] : null;

  / / render the page
  const renderContext = {
    canvasContext: context,
    transform,
    viewport,
  };
  await page.render(renderContext);
  console.log('Page rendered! '); }) ();Copy the code

For the complete code, see Pdfjs/index.tsx. The effect is as follows:

Using the Viewer API

Render using the Viewer API, which is in the pdFjs-dist /web/ PDF_viewer path.

1. Import packages

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

2. Layout the page

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

Absolute position required:

.viewer {
  position: relative;

  .container {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    overflow: scroll; }}Copy the code

3. The rendering PDF

const container = containerRef.current;
if (container == null) return;

if (hrRef.current) {
  container.style.top = `${hrRef.current.offsetTop}px`;
}

// To listen to events, you must pass PDFViewer as an instance
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');
});

/ / create the PDFViewer
const pdfViewer = new PDFViewer({
  container,
  eventBus,
  linkService: null.renderer: 'canvas'.l10n: null});/ / import Document
(async() = > {const loadingTask = pdfjsLib.getDocument(url);
  const pdf = awaitloadingTask.promise; pdfViewer.setDocument(pdf); }) ();Copy the code

For the complete code, see PdfViewer/index.tsx. The effect is as follows:

Using the Viewer HTML

Pdf.js provides viewer.html for the online demo, but not in PDfjs-dist. Compile the source code yourself.

The compile result has been placed in static/ PDFJS /, open the web/ view.html at Electron Window? File =x. df or embedded with iframe.

If you recompile yourself, the process is as follows:

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

# install dependencies
npm install -g gulp-cli
npm install

# Development run
gulp server
# http://localhost:8888/web/viewer.html

# build and publish
gulp generic
# build/generic/
Copy the code

If iframe is embedded, also open web/viewer.html? The file = x.p df:

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

The HTTP address provided by NPM run static opens as follows:

If you want to do this in Electron + React, you’ll need to figure out how to do it.

The last

Pdf.js is the perfect choice for Web rendering PDF, and many PDF Web Viewer libraries are based on it.

GoCoding personal practice experience sharing, please pay attention to the public account!