Available Now: Explore our latest release with enhanced accessibility and powerful IDP features

How to Generate a PDF with JavaScript

By Oscar Zhang | 2021 Mar 14

Sanity Image
Read time

8 min

A common requirement for web applications is a way to generate PDFs and make them available for download. This is typically to produce invoices, tickets, sales contracts, reports, and other documents personalized with customer data.

In this article, we walk you through a simple, open-source method: html2pdf.js. html2pdf uses a JavaScript library embedded in a website to make parts of it downloadable as PDFs. For this guide, we show how to generate a PDF from JavaScript in a web application from an HTML template.

Here are the steps we'll follow to convert HTML to PDF in JS:

  1. Install html2pdf.js.
  2. Grab and convert a selection of HTML using the code we provide.
  3. Optional: Include additional methods, arguments, and parameters to control how the final PDF file displays and how the HTML content is split.

And here's the schema code we'll implement:

{
  "@context": "https://schema.org",
  "@type": "HowTo",
  "name": "Generate PDFs from an HTML Template",
  "step": [
    {
      "@type": "HowToStep",
      "name": "Install html2pdf.js",
      "text": "Install the html2pdf.js library to your project in order to convert HTML to PDF."
    },
    {
      "@type": "HowToStep",
      "name": "Grab and convert HTML",
      "text": "Use the provided code to select and convert a piece of HTML into a PDF file."
    },
    {
      "@type": "HowToStep",
      "name": "Optional: Customize PDF display and HTML content",
      "text": "You can use additional methods, arguments, and parameters to control how the final PDF file looks and how the HTML content is split."
    }
  ]
}

We also explore html2pdf.js use cases and alternatives – including an open-source React-to-PDF generator and Apryse’s advanced JavaScript framework for dynamic, server-less generation of interactive, paginated PDF documents.

Use Cases for html2pdf.js

Copied to clipboard

The html2pdf.js library relies on pure JavaScript to generate a PDF. As a result, html2pdf embeds directly client-side, in the browser. Unlike using the browser print function, html2pdf enables you to create an authentic download experience for your users. It works behind your interface and seems like a natural part of your web app.

html2pdf.js is good for small document generation. It’s perfect for serving a single user who simply wants to click to create a PDF such as a concert ticket or a boarding pass.

html2pdf.js works well for certain functions:

  • Create and view simple PDFs with static, non-selectable content using this PDF viewer in JavaScript
  • Generate documents froman HTML/CSS template
  • Add a download-to-PDF function to a web app

Use HTML to Create a PDF with html2pdf.js

Copied to clipboard

Combining html2canvas and jsPDF, html2pdf relies on a simple workaround to bypass typical challenges associated with converting HTML to PDF in a browser. First, it uses html2canvas to convert your HTML to a canvas and renders that canvas to a static image. This makes it easy for jsPDF to wrap the new image in a PDF file, made downloadable to your users.

Get Started

Copied to clipboard

We’ve provided a manually typed HTML invoice template for use with this guide, but you can easily generate HTML for your own document in a backend.

Install html2pdf.js

Copied to clipboard

html2pdf.js installs in three main ways: via HTML, by NPM, or by inserting the library using JavaScript.

Install HTML

The simplest way to install html2pdf.js is to download dist/html2pdf.bundle.min.js to your project folder and include it in your HTML with the following:

<script  src="html2pdf.bundle.min.js"></script>

Install NPM

You can also install html2pdf.js and its dependencies using NPM:

npm install --save html2pdf.js

Using JavaScript (Console)

Alternatively, if you’re on a web page you can’t modify directly and want to use html2pdf.js for screenshot capture, paste the following into the console:

function addScript(url) {
  const script = document.createElement('script');
  script.type = 'application/javascript';
  script.src = url;
  document.head.appendChild(script);
}
addScript('https://raw.githack.com/eKoopmans/html2pdf/master/dist/html2pdf.bundle.js');

Basic Usage

Copied to clipboard

You can use html2pdf.js as soon as it is installed. The following code grabs and converts a selection of HTML, and then prompts the user to “save.”

const element = document.querySelector('body');
html2pdf(element);

Our example invoice then displays as such when opened:

HTML to PDF in JS: Invoice template example view

Advanced Usage

Copied to clipboard

If called without arguments, html2pdf.js returns a worker object. This worker in turn supports several methods and arguments. The library’s Promise-based API lets you chain methods sequentially, insert your own intermediate steps, or skip steps without difficulty.

For this guide, we won’t do anything fancy; instead, we'll just stick to the default flow:

// This will implicitly create the canvas and PDF objects before saving.
const worker = html2pdf().from(element).save();
// The basic workflow of html2pdf.js tasks (enforced by the prereq system) is:
// .from() -> .toContainer() -> .toCanvas() -> .toImg() -> .toPdf() -> .save()

Optional Parameter

Copied to clipboard

Additionally, html2pdf.js accepts an optional parameter with settings to control how the final PDF file displays and the to-image workaround used for conversion.

const element = document.querySelector('body');
const opt = {
  filename: 'myPage.pdf',
  margin: 2,
  image: {type: 'jpeg', quality: 0.9},
  jsPDF: {format: 'letter', orientation: 'portrait'}
};
// New Promise-based usage:
html2pdf().set(opt).from(element).save();
// Old monolithic-style usage:
html2pdf(element, opt);

Page-Break Examples

Copied to clipboard

Lastly, we can programmatically add page breaks to our PDFs to control how the HTML content is split. Add page breaks via CSS styles, selectors on individual elements, or avoided (via the avoid-all mode).

// Avoid page-breaks on all elements, and add one before #pageX.
html2pdf().set({
  pagebreak: {mode: 'avoid-all', before:'#pageX'}
});
// Adds page-breaks according to the CSS break-before, break-after, and break-inside properties.
// Only recognizes always/left/right for before/after, and avoid for inside.
html2pdf().set({
  pagebreak: {mode: 'css' }
});

Short invoices don’t require page breaks. But you are required to add breaks on longer documents or documents with complex content, such as those with large images and tables, due to browser limits on how big canvases can get. (html2pdf uses a single canvas when creating each page.)

Using html2pdf.js: Advantages

Copied to clipboard

html2pdf.js is great at creating an authentic download experience for your users who want to produce simple PDFs from a webpage.

Since html2pdf.js merges information client-side, files do not cross a network multiple times. Therefore, it is reliable and infinitely scalable for each user who wants to download from your app. And your user experience is less impacted by any network latency or servers under heavy load.

Client-side implementation of html2pdf.js simplifies due diligence as well, if your data has a sensitive nature (e.g., personal, financial and/or health).

PDF viewer in JavaScript: Infographic diagram of pdf document generation information flows

Serverless PDF generation improves the security, performance, reliability, and scalability of your download experience.

Using html2pdf.js: Disadvantages

Copied to clipboard

However, the library also has a few limitations noted by the open-source community. Many are tied to relying on the browser <canvas> workaround to produce a static image of content then wrapped in a PDF.

html2pdf.js limitations

  • Your PDFs won’t be interactive (i.e., no searchable and selectable text)
  • Rendering with html2pdf.js “isn’t perfect” since it relies on the built-in browser rendering function
  • You have to add pagination programmatically

You may also experience:

  • Larger file sizes due to producing pages as large images
  • Blurriness in text

Comparison: HTML vs. Office Template Generation

Copied to clipboard

Another consideration is converting HTML to PDF in JS vs. using templates in other formats such as Office (docx, pptx, and xlsx, as well as legacy Office formats).

HTML is great for simple documents where content is relatively static and/or limited to one page.

But it is less ideal for paginated documents, especially if your content needs to adjust dynamically when populated and it reflows across pages, since HTML was designed for webpages without pagination.

In contrast, Office templates have pagination baked into the logic of the format, making implementation of dynamic generation easier. As a bonus, users can upload their own templates in open Office formats created in their familiar Office tools. This makes it easy to recycle from an existing repository.

WebViewer has a built-in Office engine to generate PDFs from templates in Office formats, without requiring servers, Microsoft Office software, or Microsoft Office licenses. It drops into any web app directly and supports all modern frameworks including React, Angular, Vue, Blazor, etc.

Alternatives to html2pdf.js

Copied to clipboard

To produce compact, high-fidelity PDFs with interactive (searchable/selectable) text, we’d suggest another method.

There are various open source libraries and methods. For example:

React-to-PDF Generation

One alternative we’ve written a tutorial on lets you create styled PDFs via a React PDF generator.

This React-to-PDF method works via a Node service and headless Chrome, and uses HTML templates. (Puppeteer and Babel-node are its dependencies.)

You must integrate a server component in order to handle the conversion. If you’re fine with that, then you’re good to go.

Text and other content is not rendered via canvas as static images, meaning React to PDF has advantages over html2pdf:

  • Your files are more compact
  • Your text is searchable and selectable
  • Your PDFs print faster and at higher fidelity
  • Complex content renders at higher fidelity

Server-less, Dynamic Generation of Paginated PDFs

On the other hand, maybe you want the best of two worlds — an authentic download experience that you can embed in your app directly to generate beautiful, paginated PDF documents.

Next, we consider a solution that lets you:

  • Generate interactive, paginated and/or complex documents in the browser for your users to download or print
  • Leverage the same server-less advantages of html2pdf.js
  • Support additional features not easily possible with Puppeteer, such as form filling
  • Simplify tables that span pages

For this use case, consider our advanced JS framework — WebViewer from-Office template generation. This PDF viewer in JavaScript brings native, dynamic PDF generation into the browser to embed in any web app. This results in very easy to create complex PDF documents in seconds.

WebViewer document generation is the same process for both client-side or server-side generation; it uses the same templates, the same APIs, and the same logic to create pixel-perfect documents. It merges in JSON data client-side and leverages any Office file templates (docx, pptx, xlsx, and legacy Office formats).

No servers, Microsoft Office licenses, Microsoft Office software, or plugins are required.

Quote

Unlock the power of document generation with Apryse. Simplify document assembly, enhance efficiency, and streamline your processes. Get started today!

WebViewer JS Doc Gen Features

WebViewer uses pagination logic, so formatting is better. Additionally, it uses table spanning logic to create headers consistently across all pages, whereas HTML breaks the header so it appears only on the first page.

Other WebViewer doc gen features include:

  • Automatic detection of your template styles and formatting
  • Dynamic reflow of text around added images and figures
  • Conditionals and loops

Finally, this technology leverages the leading accuracy of the Apryse SDK. So you can count on your PDFs to render and for content to reflow as expected. You also have access to the leading support and hundreds of other JS features of the Apryse SDK if you wish to extend your solution, adding additional document functionality such as form creation, watermarking, and so on.

Get Started using WebViewer JS PDF Generation

Copied to clipboard

Apryse’s advanced JavaScript PDF generator requires minimal code to get up and running. Download WebViewer to your project and follow the instructions found in the from-Office generation guide. Later, consider extending your solution. Dive deep into the PDF generation library or WebViewer’s many other server-less capabilities.

Quote

Here is an informative resource for individuals interested in learning how to create a docx file and convert it to a PDF using JavaScript.

Conclusion

Copied to clipboard

Generating a PDF from a website using JS is no piece of cake. But following this guide, you can now generate a PDF with JavaScript, like invoices, right in your web app and make those PDFs downloadable by your users!

We also looked at html2pdf.js use cases and alternatives such as a React PDF generator.

The bottom line: If you need a quick, simple conversion and don’t care about pagination, html2pdf is a good server-less PDF gen component. However, if you need to create more complex documents or if formatting is important, check out WebViewer’s document generation framework. It lets you embed a fast, authentic download experience for your users, and provides more flexibility than other alternatives via its server-less PDF generator.

To learn more about PDF generation, check out the Apryse PDF SDK.

Sanity Image

Oscar Zhang

Share this post

email
linkedIn
twitter