Blog Post

How to Convert HTML to PDF Using React

Illustration: How to Convert HTML to PDF Using React

In this tutorial, you’ll learn how to convert HTML into PDF using React, one of the most popular JavaScript libraries. To achieve this, you’ll use an open source package called jsPDF, which is a client-side library that doesn’t require any server-side processing. You’ll use the latest version, 2.5.1. jsPDF can be used to generate reports, invoices, and tickets.

What Can You Convert into PDF via jsPDF?

If you look at the live demo examples of jsPDF, you can see it’s possible to convert images, font faces, font sizes, circles, rectangles, triangles, tables, lines, languages, and more into PDF format. You can also convert HTML into multiple pages with page breaks and add password protection and annotations. It’s also possible to change the orientation of a page to landscape or portrait.

Setting Up a React Project

To get started, you’ll use Create React App. This will create a new React project with all the necessary dependencies and configuration files:

npx create-react-app convert-html-to-pdf

Change to the newly created directory and install the jspdf package through npm or yarn:

cd convert-html-to-pdf
npm install jspdf
yarn add jspdf

Using the jsPDF Library

  1. Now, open the App.js file and import the jspdf package:

import jsPDF from 'jspdf';
  1. Initialize a new instance of jsPDF:

const doc = new jsPDF();

jsPDF provides some options to customize a PDF. By default, it’ll use A4 paper size, portrait orientation, and millimeters as a unit of measurement.

If you want to change any of these options, you can pass an object to the constructor:

const doc = new jsPDF({
	orientation: 'landscape',
	unit: 'in',
	format: [4, 2],
});

You can find all the available options in the jsPDF documentation.

Converting HTML to PDF

jsPDF provides a method called html() to convert HTML to PDF. It takes two arguments: the HTML element, and a callback function. Since you’re using React, to get a reference to the HTML element, use the useRef() hook.

The doc.save() method takes the name of the PDF file as an argument. It’ll download the PDF file to the user’s computer:

doc.html(html_element, {
	async callback(doc) {
		await doc.save('pdf_name');
	},
});

Adding the Markup

To convert HTML to PDF, you need to add the markup to the page. You’ll use a report template with a button. When the button is clicked, you’ll trigger an event to generate the PDF. The div element will contain the HTML that you want to convert to PDF.

Create a new file called ReportTemplate.js and add the following code:

const ReportTemplate = () => {
	const styles = {
		page: {
			marginLeft: '5rem',
			marginRight: '5rem',
			'page-break-after': 'always',
		},

		columnLayout: {
			display: 'flex',
			justifyContent: 'space-between',
			margin: '3rem 0 5rem 0',
			gap: '2rem',
		},

		column: {
			display: 'flex',
			flexDirection: 'column',
		},

		spacer2: {
			height: '2rem',
		},

		fullWidth: {
			width: '100%',
		},

		marginb0: {
			marginBottom: 0,
		},
	};
	return (
		<>
			<div style={styles.page}>
				<div>
					<h1 style={styles.introText}>
						Report Heading That Spans More Than Just One Line
					</h1>
				</div>

				<div style={styles.spacer2}></div>

				<img style={styles.fullWidth} src="photo-2.png" />
			</div>

			<div style={styles.page}>
				<div>
					<h2 style={styles.introText}>
						Report Heading That Spans More Than Just One Line
					</h2>
				</div>

				<div style={styles.columnLayout}>
					<div style={styles.column}>
						<img style={styles.fullWidth} src="photo-2.png" />
						<h4 style={styles.marginb0}>Subtitle One</h4>
						<p>
							Lorem ipsum dolor sit amet, consectetur adipiscing
							elit, sed do eiusmod tempor incididunt ut labore et
							dolore magna aliqua.
						</p>
					</div>

					<div style={styles.column}>
						<img style={styles.fullWidth} src="photo-1.png" />
						<h4 style={styles.marginb0}>Subtitle Two</h4>
						<p>
							Lorem ipsum dolor sit amet, consectetur adipiscing
							elit, sed do eiusmod tempor incididunt ut labore et
							dolore magna aliqua.
						</p>
					</div>
				</div>

				<div style={styles.columnLayout}>
					<div style={styles.column}>
						<img style={styles.fullWidth} src="photo-3.png" />
						<h4 style={styles.marginb0}>Subtitle One</h4>
						<p>
							Lorem ipsum dolor sit amet, consectetur adipiscing
							elit, sed do eiusmod tempor incididunt ut labore et
							dolore magna aliqua.
						</p>
					</div>

					<div style={styles.column}>
						<img style={styles.fullWidth} src="photo-4.png" />
						<h4 style={styles.marginb0}>Subtitle Two</h4>
						<p>
							Lorem ipsum dolor sit amet, consectetur adipiscing
							elit, sed do eiusmod tempor incididunt ut labore et
							dolore magna aliqua.
						</p>
					</div>
				</div>
			</div>
		</>
	);
};

export default ReportTemplate;

Here, you added some filler images to the report template. You can replace them with your own images. As for the styling, you used inline styles because jsPDF doesn’t support external stylesheets.

Generating the PDF

Now that you have the JSX in place, you can handle the button click. You’ll use the onClick event handler to call the handlePDF function.

Go back to App.js and add the onClick event handler to the button. After that, import the useRef hook and the reference to the HTML element:

import { useRef } from 'react';
import jsPDF from 'jspdf';
import ReportTemplate from './ReportTemplate';

function App() {
	const reportTemplateRef = useRef(null);

	const handleGeneratePdf = () => {
		const doc = new jsPDF({
			format: 'a4',
			unit: 'px',
		});

		// Adding the fonts.
		doc.setFont('Inter-Regular', 'normal');

		doc.html(reportTemplateRef.current, {
			async callback(doc) {
				await doc.save('document');
			},
		});
	};

	return (
		<div>
			<button className="button" onClick={handleGeneratePdf}>
				Generate PDF
			</button>
			<div ref={reportTemplateRef}>
				<ReportTemplate />
			</div>
		</div>
	);
}

export default App;

The app is now ready to generate PDFs. You can run the app with npm start and click the button to generate the PDF.

Adding Custom Fonts

jsPDF has support for 14 standard PDF fonts. To add custom fonts, you need to use a font converter. Navigate to this font converter and upload .ttf files.

Click Choose Files to choose the fonts you want to add. After that, click Create to convert the fonts. You don’t need to modify fontName, fontStyle, or Module format.

font converter

The font converter will generate a JavaScript file with the provided .ttf file as a base64-encoded string and some code for the jsPDF. Add the generated JavaScript file to your project.

To activate the custom font, use the setFont() method:

doc.setFont('Inter-Regular', 'normal');

You can find the font name before you convert the font to JavaScript. If you’re using more than one font, you need to go through the same process for each font.

You can find the demo project on CodeSandbox. Feel free to fork it and play around with it. The fonts and images used in the demo project are in the public folder.

Create PDFs with React to PDF

Disadvantages of Using the jsPDF Library

While jsPDF is a good library for generating PDF documents in client-side JavaScript, it has some disadvantages:

  • The provided documentation is somewhat hard to follow.
  • If you want to add custom fonts, you need to use a font converter.
  • The jsPDF repository seems to be a bit outdated.
  • The library doesn’t support external stylesheets.

Conclusion

In this tutorial, we looked at how to generate client-side PDFs from HTML/JSX using React. If you’re looking to add more robust PDF capabilities, PSPDFKit offers a commercial React PDF library that can easily be integrated into your web application. It comes with 30+ features that let you view, annotate, edit, and sign documents directly in your browser. Out of the box, it has a polished and flexible UI that you can extend or simplify based on your unique use case.

You can also deploy our vanilla JavaScript PDF viewer or use one of our many web framework deployment options like React.js, Angular, and Vue.js. To see a list of all web frameworks, start your free trial. Or, launch our demo to see our viewer in action.

Related Products
Share Post
Free 60-Day Trial Try PSPDFKit in your app today.
Free Trial

Related Articles

Explore more
TUTORIALS  |  Web • PDF.js • JavaScript • How To • PDF Viewer

How to Print PDFs Using PDF.js

BLOG  |  Web • C++ • WebAssembly

Render Performance Improvements in PSPDFKit for Web

PRODUCT  |  Web

Handling Browser Support of Media Files in PSPDFKit for Web