Can generating a PDF file in a React app actually be simple? With KendoReact, YES!
A popular question that I see pop up in React communities is how to export HTML, or parts of your React application, to PDF. Normally this can be a bit cumbersome, but I’m here to tell you that, thanks to KendoReact, we can now export any and all content in our React apps as easy as 1-2-3!
Today’s blog post is the first of a three-part series that covers how you can generate PDF from HTML in React. As this is Part 1, today we will first create a quick app to be exported, add our React PDF Generator library and see how to generate a PDF file from HTML in React.
In Part 2, we’ll build a sample invoice in our React app using HTML and CSS, then generate a PDF file based on this content.
In Part 3, we'll learn how to export to PDF advanced React UI components such as the KendoReact Data Grid and React TreeList.
In case you prefer to learn through videos rather than reading blog posts, I recorded a video series on how to generate PDF in React apps. Check out Part 1 of the PDF export video series right here.
This may be obvious, but to export something to PDF you first have to have that something! As you have stumbled upon this article, I think you have a set of requirements already but for those of you curious here are some common scenarios I’ve seen that folks need to export React apps to PDF:
There are, of course, tons more scenarios, but these are just some that I’ve discussed with React developers over the years.
For this blog post, I’m going to keep things simple. Before we get started, I’m going to toss out a link to the following GitHub repo. For this blog post, we will be looking at the ExportExample
component in the GitHub project. This will contain everything I’m talking about today, and then some (keep an eye out for more content around this project!). For those of you following along with this source code, we’ll be looking at the ExportExample
component.
Before jumping into the HTML and CSS that makes up my component, I just want to note that this example showcases the following types of HTML and exports it to PDF:
<h1/>
, <img />
, <span />
, etc.To kick things off, I’ve just set up a fresh project using create-react-app.
All you need to follow along is the following HTML:
<div className="app-content">
<div>
<h1>KendoReact PDF Processing</h1>
<img src={kendoka} alt="Kendo UI Kendoka" />
<p>This is an example of text that may be <span className="neat-style">styled</span>
</p>
</div>
</div>
For the image, I’ve added the following image and defined it as the kendoka
variable above.
And here is our CSS that we can toss in to our existing App.css
:
.app-content {
text-align: center;
background-color: #282c34;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: calc(10px + 2vmin);
color: white;
}
.page-container {
margin: 1em;
}
.neat-style {
color: rgb(255, 142, 166);
font-weight: bold;
text-decoration: underline;
}
.button-area button {
margin-right: 10px;
}
.k-pdf-export {
background-color: #282c34;
}
Now that we have our HTML and CSS, let’s get to the next step and add in KendoReact PDF Processing!
To get started with generating a PDF in React apps, all we need to do is head over to the KendoReact PDF Generator documentation section. This gives you the instructions for how to install the KendoReact PDF Generator, and it also contains all the documentation articles you need to get started and dive deeper in to the world of React PDF generation on the client side—I highly recommended you bookmark this!
That being said, the main bit of information we’re interested in is the following npm command:
npm install --save @progress/kendo-react-pdf @progress/kendo-drawing @progress/kendo-licensing
A quick note: You may have noticed the @progress/kendo-licensing
package included here. KendoReact is a commercial UI component library and as a part of this you will need to provide a license key when you use the components in your React projects. You can snag a license key through a free trial or by owning a commercial license. For more information, you can head over to the KendoReact Licensing page.
With that out of the way, we are ready to move on to the exporting. That’s right—we’re technically ready to rock and roll. As a bare minimum, all we need is to is add this one single package and one single import statement in our app and we can move on to the next step. Really, that’s all we need! One single package and you can skip straight to Step 3.
However, I do also want to take this time to import one extra component, namely the KendoReact Button component. This is purely because I like the look and feel of the KendoReact button. As a part of this, I also installed one of the KendoReact themes to help with the overall look and feel of said buttons and any future KendoReact components. In this case, I added the KendoReact Material theme. If you’re interested in this partial step, or want to include this yourself, you can follow the installation instructions in the linked documentation article.
Before I show you how you can export your React app to PDF (Step #3), I’m going to toss some new HTML markup at you. This includes some new KendoReact Buttons and just an extra <div>
element, so nothing too crazy.
<div className="app-content">
<div>
<h1>KendoReact PDF Processing</h1>
<img src={kendoka} alt="Kendo UI Kendoka" />
<p>This is an example of text that may be <span className="neat-style">styled</span>
</p>
<div className="button-area">
<Button primary={true}>Export with Component</Button>
<Button>Export with Method</Button>
</div>
</div>
</div>
If you’ve followed along so far, all you would need to do is copy and paste everything above in to your own project and you’ll be good to go!
Now that we have everything installed let’s actually get to a point where we can export content! First off, let’s make sure that we import the KendoReact PDF Generator library in our appropriate React component:
import { PDFExport, savePDF } from '@progress/kendo-react-pdf';
The two items we have imported here represent two methods of exporting: PDFExport
exports content as a component, and savePDF
is used when we want to export things via a method. Let’s dive into each approach!
All we need to do to export content via the component route is to find the content that we want to export and wrap around the HTML with <PDFExport></PDFExport>
tags. You don’t need to wrap around your entire React app—just the content that needs to be exported.
To give you an idea of what this looks like, here is our previous HTML wrapped appropriately:
<div className="app-content">
<PDFExport ref={pdfExportComponent} paperSize="A4">
<div>
<h1>KendoReact PDF Processing</h1>
<img src={kendoka} alt="Kendo UI Kendoka" />
<p>This is an example of text that may be <span className="neat-style">styled</span>
</p>
<div className="button-area">
<Button primary={true}>Export with Component</Button>
<Button>Export with Method</Button>
</div>
</div>
</PDFExport>
</div>
You may have noticed two things above: one is that we define a reference to this component via React’s ref
prop, so we have ref={pdfExportComponent}
, and we also define the paperSize
to A4. Paper size can be set both via the same prop as I show here, or even through CSS (more on this in a future blog post), but since A4 is the most basic paper size, I just went ahead and added it here.
Now that we’ve defined the area that we want to export, let’s go ahead and actually export content on a button click! First, we’ll define our onClick
event handler:
<Button primary={true} onClick={handleExportWithComponent}>Export with Component</Button>
Next, here’s our actual handler:
const handleExportWithComponent = (event) => {
pdfExportComponent.current.save();
}
What we are doing here is grabbing the ref
variable we defined as a reference to our <PDFExport></PDFExport>
tags. From there we use the available API to call .save()
and our content will be exported!
Similar to the component approach above, exporting via a method needs to define a parent HTML element that should contain all the content which is set to be exported. The quickest way to do this is to define a <div>
element with a ref
prop. Of course, we also need a button responsible for exporting on click, so we’ll add that in here as well.
Expanding upon the HTML we have so far, we have:
<div className="app-content">
<div ref={contentArea}>
<h1>KendoReact PDF Processing</h1>
<img src={kendoka} alt="Kendo UI Kendoka" />
<p>This is an example of text that may be <span className="neat-style">styled</span
</p>
<div className="button-area">
<Button primary={true}>Export with Component</Button>
<Button onClick={handleExportWithFunction}>Export with Method</Button>
</div>
</div>
</div>
Then, in our event handler we have the following code:
const handleExportWithFunction = (event) => {
savePDF(contentArea.current, { paperSize: "A4" });
}
What this bit of code is doing is calling the React PDF Generator savePDF method and passing in the HTML through contentArea.current
along with an object reflecting the options we want to set for the file we are exporting. In this case, I’m only setting the paperSize
option to show you how this all looks in comparison to the declarative and component approach, but you have a huge list of options available to you that you can customize!
That’s all there is to it! Through either approach, you now know how to generate a PDF file from HTML in React. Whether you prefer the declarative approach of wrapping around your content, or if you want to just pass in a block of HTML as content in to a method, the power of React PDF Generator is that any and all content can be exported using these two simple approaches.
In Part 2 of this series, Generating PDF from HTML in React Demo: Exporting Invoices, we create a more advanced HTML and CSS layout and see how we can customize the size of the layout of the generated PDF file via CSS and even do so dynamically!
Carl Bergenhem was the Product Manager for Kendo UI.