Blog Post

How to convert HTML to PDF in React

Illustration: How to convert HTML to PDF in React
Information

This article was first published in October 2022 and was updated in August 2024.

Converting HTML to PDF in React is a powerful feature for generating dynamic reports, invoices, and more directly from your web applications. In this post, we’ll walk you through the process using jsPDF, a popular client-side library. Whether you’re creating a report or a ticket, this tutorial will help you smoothly integrate PDF generation into your React project.

What can you convert into PDF with 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 jsPDF in your React project

To get started with React HTML-to-PDF conversion, you’ll use Vite. This will create a new React project with all the necessary dependencies and configuration files:

npm create vite@latest convert-html-to-pdf -- --template react

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

Step-by-step guide to converting HTML to PDF

  1. Now, open the App.jsx 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.

  1. 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.jsx and add the following code:

const styles = {
	page: {
		marginLeft: '5rem',
		marginRight: '5rem',
		color: 'black',
		backgroundColor: 'white',
	},

	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,
	},
};

const ReportTemplate = () => {
	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. 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.jsx 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 run dev 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.

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

font converter

The font converter will generate a JavaScript file with the provided .ttf file as a base64-encoded string and some code for 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.

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

This tutorial looked at how to generate client-side PDFs from HTML/JSX using React. If you’re looking to add more robust PDF capabilities, Nutrient 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.

FAQ

Here are a few frequently asked questions about converting HTML to PDF in React.

How can I convert HTML to PDF in a React application?

You can use the jsPDF library to convert HTML to PDF in a React application. This library helps render HTML content to a PDF format.

What are the steps to integrate jsPDF with React?

Install the jsPDF library using npm, import it into your React component, and use it to capture and convert the HTML content to PDF by triggering the conversion on a specific user action.

Can I customize the PDF generated in a React application?

Yes, you can customize the PDF by adjusting the HTML and CSS of the content being converted. The jsPDF library also allows you to set options like page size, and orientation.

What are the benefits of using React for HTML-to-PDF conversion?

React allows for a dynamic and interactive UI, making it easy to create and manage the content that will be converted to PDF. React’s component-based architecture helps in reusing and maintaining the code efficiently.

What are some common use cases for converting HTML to PDF in React applications?

Common use cases include creating downloadable reports, invoices, user manuals, and other documents that require a printable format from a web application.

Author
Hulya Masharipov Technical Writer

Hulya is a frontend web developer and technical writer at PSPDFKit who enjoys creating responsive, scalable, and maintainable web experiences. She’s passionate about open source, web accessibility, cybersecurity privacy, and blockchain.

Related products
Share post
Free trial Ready to get started?
Free trial