Skip to content
Create and modify PDF documents in any JavaScript environment
Branch: master
Clone or download
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
.circleci Remove gulp and add CONTRIBUTORS.md (#53) Dec 17, 2018
__integration_tests__
__tests__
docs Update docs Dec 30, 2018
examples Update pdf-lib version in examples/ Mar 9, 2019
src change normalize method visibility (#81) Mar 12, 2019
test-pdfs Add integration tests (#57) Dec 24, 2018
.gitignore Add profiling command Aug 18, 2018
.prettierrc.json
CONTRIBUTING.md
LICENSE.md
Makefile.js
README.md
TODO.md
package.json
pdf_specification.pdf
rollup.config.js
tsconfig.json Enable strictNullChecks tsc option Jul 6, 2018
tslint.json Copy pages across PDFs (#52) Dec 16, 2018
typedoc.js Update docs Aug 19, 2018
yarn.lock Minor cleanup Feb 24, 2019

README.md

pdf-lib

Create and modify PDF documents in any JavaScript environment.
Designed to work in any modern JavaScript runtime. Tested in Node, Browser, and React Native environments.

Table of Contents

Motivation

pdf-lib was created to address the JavaScript ecosystem's lack of robust support for PDF manipulation (especially for PDF modification).

Two of pdf-lib's design requirements since its inception are to:

  1. Support modification (editing) of existing documents.
  2. Work in all JavaScript environments - not just in Node or the browser.

There are other good open source JavaScript PDF libraries available. However, most of them can only create documents, they cannot modify existing ones (e.g. pdfkit, jspdf, pdfmake). hummus is a NodeJS library capable of both creating and modifying PDF documents. However, hummus is a Node wrapper around a C++ library. This means that it cannot run in all JavaScript environments. For example, you cannot use hummus in the Browser or in React Native.

Features

  • Create new PDFs
  • Modify existing PDFs
  • New: Copy pages between PDFs
  • Add Pages
  • Insert Pages
  • Remove Pages
  • Draw Text
  • Draw Images
  • Draw Vector Graphics
  • Embed Fonts
    • New: UTF-8 and UTF-16 character sets are supported
    • New: Measure width and height of text
  • Embed Images

Usage Examples

More detailed examples are available here.

Document Creation

import { PDFDocumentFactory, PDFDocumentWriter, StandardFonts, drawText } from 'pdf-lib';

const pdfDoc = PDFDocumentFactory.create();
const [timesRomanRef, timesRomanFont] = pdfDoc.embedStandardFont(
  StandardFonts.TimesRoman,
);

const page = pdfDoc
  .createPage([350, 500])
  .addFontDictionary('TimesRoman', timesRomanRef);

const contentStream = pdfDoc.createContentStream(
  drawText(timesRomanFont.encodeText('Creating PDFs in JavaScript is awesome!'), {
    x: 50,
    y: 450,
    size: 15,
    font: 'TimesRoman',
    colorRgb: [0, 0.53, 0.71],
  }),
);

page.addContentStreams(pdfDoc.register(contentStream));

pdfDoc.addPage(page);

const pdfBytes = PDFDocumentWriter.saveToBytes(pdfDoc);

Document Modification

import { PDFDocumentFactory, PDFDocumentWriter, StandardFonts, drawText } from 'pdf-lib';

// This should be a Uint8Array.
// This data can be obtained in a number of different ways.
// If your running in a Node environment, you could use fs.readFile().
// In the browser, you could make a fetch() call and use res.arrayBuffer().
const existingPdfDocBytes = ...

const pdfDoc = PDFDocumentFactory.load(existingPdfDocBytes);
const [helveticaRef, helveticaFont] = pdfDoc.embedStandardFont(
  StandardFonts.Helvetica,
);

const pages = pdfDoc.getPages();
const page  = pages[0];

page.addFontDictionary('Helvetica', helveticaRef);

const contentStream = pdfDoc.createContentStream(
  drawText(helveticaFont.encodeText('This text was added to the PDF with JavaScript!'), {
    x: 25,
    y: 25,
    size: 24,
    font: 'Helvetica',
    colorRgb: [0.95, 0.26, 0.21],
  }),
);

page.addContentStreams(pdfDoc.register(contentStream));

const pdfBytes = PDFDocumentWriter.saveToBytes(pdfDoc);

Copying Pages

import { PDFDocumentFactory, PDFDocumentWriter } from 'pdf-lib';

// These should be a Uint8Arrays. (see Document Modification example for more details)
const firstDonorPdfBytes = ...
const secondDonorPdfBytes = ...

const firstDonorPdfDoc = PDFDocumentFactory.load(firstDonorPdfBytes);
const secondDonorPdfDoc = PDFDocumentFactory.load(secondDonorPdfBytes);

// We'll copy the fourth page from the first donor document, and the
// first page from the second donor document.
const firstDonorPage = firstDonorPdfDoc.getPages()[3];
const secondDonorPage = secondDonorPdfDoc.getPages()[0];

const pdfDoc = PDFDocumentFactory.create();

// Copy over the pages from the donor documents into our new document
pdfDoc.addPage(firstDonorPage);
pdfDoc.insertPage(0, secondDonorPage);

const pdfBytes = PDFDocumentWriter.saveToBytes(pdfDoc);

Embed Font and Measure Text

This example demonstrates the use of the font.widthOfTextAtSize() and font.heightOfFontAtSize() methods for a font embedded with pdfDoc.embedNonstandardFont. But note that these methods also exist on standard fonts embedded with pdfDoc.embedStandardFont.

import { PDFDocumentFactory, PDFDocumentWriter, drawText, drawRectangle } from 'pdf-lib';

// This should be a Uint8Array.
// This data can be obtained in a number of different ways.
// If your running in a Node environment, you could use fs.readFile().
// In the browser, you could make a fetch() call and use res.arrayBuffer().
const fontBytes = ...

const pdfDoc = PDFDocumentFactory.create();
const [fontRef, font] = pdfDoc.embedNonstandardFont(fontBytes);

const page = pdfDoc
  .createPage([350, 500])
  .addFontDictionary('FontName', fontRef);

const text = 'This is text in an embedded font!';
const textSize = 15;
const textWidth = font.widthOfTextAtSize(text, textSize);
const textHeight = font.heightOfFontAtSize(textSize);

const contentStream = pdfDoc.createContentStream(
  // Draw text on page
  drawText(font.encodeText(text), {
    x: 50,
    y: 450,
    size: textSize,
    font: 'FontName',
    colorRgb: [0, 0.53, 0.71],
  }),
  // Draw a box around the text
  drawRectangle({
    x: 50,
    y: 450,
    width: textWidth,
    height: textHeight,
    borderColorRgb: [1],
    borderWidth: 0.5,
  }),
);

page.addContentStreams(pdfDoc.register(contentStream));

pdfDoc.addPage(page);

const pdfBytes = PDFDocumentWriter.saveToBytes(pdfDoc);

Installation

NPM Module

To install the latest stable version:

# With npm
npm install --save pdf-lib

# With yarn
yarn add pdf-lib

This assumes you're using npm or yarn as your package manager.

UMD Module

You can also download pdf-lib as a UMD module from unpkg. The UMD builds have been compiled to ES5, so they should work in any modern browser. UMD builds are useful if you aren't using a package manager or module bundler. For example, you can use them directly in the <script> tag of an HTML page.

The following builds are available:

When using a UMD build, you will have access to a global window.PDFLib variable. This variable contains all of the classes and functions exported by pdf-lib. For example:

// NPM module
import { PDFDocumentFactory, drawText } from 'pdf-lib';

// UMD module
var PDFDocumentFactory = PDFLib.PDFDocumentFactory;
var drawText = PDFLib.drawText;

API Documentation

API documentation is available here.

Contributing

We welcome contributions from the open source community! If you are interested in contributing to pdf-lib, please take a look at the CONTRIBUTING.md file. It contains information to help you get pdf-lib setup and running on your machine.

Prior Art

  • pdfkit is a PDF generation library for Node and the Browser. This library was immensely helpful as a reference and existence proof when creating pdf-lib. pdfkit's code for font embedding, PNG embedding, and JPG embedding was especially useful.
  • jspdf is a PDF generation library for the browser.
  • pdfmake is a PDF generation library for the browser.
  • hummus is a PDF generation and modification library for Node environments. hummus is a Node wrapper around a C++ library.
  • react-native-pdf-lib is a PDF generation and modification library for React Native environments. react-native-pdf-lib is a wrapper around C++ and Java libraries.
  • pdfassembler is a PDF generation and modification library for Node and the browser. It requires some knowledge about the logical structure of PDF documents to use.

License

MIT

You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.