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:
And here's the schema code we'll implement:
Plain text "@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.
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:
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.
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.
html2pdf.js installs in three main ways: via HTML, by NPM, or by inserting the library using JavaScript.
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:
You can also install html2pdf.js and its dependencies using NPM:
npm install --save html2pdf.js
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:
JavaScriptfunction 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');
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.”
JavaScriptconst element = document.querySelector('body'); html2pdf(element);
Our example invoice then displays as such when opened:
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:
JavaScript// 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()
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.
JavaScriptconst 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);
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).
JavaScript// 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.)
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).
Serverless PDF generation improves the security, performance, reliability, and scalability of your download experience.
However, the library also has a few limitations noted by the open-source community. Many are tied to relying on the browser workaround to produce a static image of content then wrapped in a PDF.
html2pdf.js limitations
You may also experience:
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.
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:
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:
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:
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.
Unlock the power of document generation with Apryse. Simplify document assembly, enhance efficiency, and streamline your processes. Get started today!
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:
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.
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.
Here is an informative resource for individuals interested in learning how to create a docx file and convert it to a PDF using JavaScript.
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.