Download HTML as a PDF in React
Tags: react, aws, javascript, programming
Published: 2023-06-11 10:12:23

**_To read more articles like this, [visit my blog](https://www.mdfaisal.com/blog)_**



Downloading PDF is a common use-case in modern front-end applications. But building PDF on the client-side can be painful. In React we have some awesome libraries like [react-pdf/renderer](https://www.npmjs.com/package/@react-pdf/renderer) to help us.

### Problems With the Traditional Libraries

`react-pdf/renderer` is an awesome library and provides lots of customization. but it comes with its own cost. For example

* You have to design a separate component for your PDF document

* Sometimes the rendering fails if you don’t handle edge-cases properly

* You have to style separately and according to their specification.

All of these are okay if you want to build a data-heavy and customized PDF. But what if you want something simpler?
>  What if you just want to print the component that is being rendered as it is?

Let’s see how we can download any component as a PDF using a neat trick and some JavaScript knowledge.

## Overview

The process that we are going to follow is converting the HTML element into an image and then putting the image into another powerful PDF library.
>  HTML document -> Image -> PDF

For this, we need two libraries.

 1. [html2canvas](https://www.npmjs.com/package/html2canvas) -> will convert our HTML document to image

 2. [jspdf](https://www.npmjs.com/package/jspdf) -> will insert the generated image into a PDF file

*The fullomplete code is at the bottom. If you are interested only in that go there directly. Otherwise bear with me. It won’t take long*

### Step 1. Install Dependencies

First, install the required dependencies.

```js
yarn add jspdf html2canvas
```

### STEP 2: Add The Downloader Function

Now Either create a separate component for your `GenericPdfdownloader` or put the following code inside the component you want to download.

```js
const downloadPdfDocument = (rootElementId) => {
  const input = document.getElementById(rootElementId);
  html2canvas(input)
    .then((canvas) => {
        const imgData = canvas.toDataURL('image/png');
        const pdf = new jsPDF();
        pdf.addImage(imgData, 'JPEG', 0, 0);
        pdf.save("download.pdf");
    })
}
```

## What the code is doing

* `Input` -> This function takes `rootElementId` as input. This will be the id of the downloadable component. We can define the id of any element like the following

```js
return <div id="divToDownload">  

  // YOUR OTHER COMPONENT CODE GOES HERE

</div>
```

So if we want to download the component inside the `div` with the `id=”divToDownload”` then we have to pass `”divToDownload”` into the function

`1. Getting the HTML Element`

In the next step, we are getting the HTML element with the passed Id.

```js
const input = document.getElementById(rootElementId);
```

`2. Converting HTML to Image`

Next, we pass the element into the `html2canvas` which gives us back an image

```js
html2canvas(input)
    .then((canvas) => {
        const imgData = canvas.toDataURL('image/png');
    })
```

`3. Putting The Image into PDF`

Next, we create a new PDF document and put the image inside that.

```js
const pdf = new jsPDF();
pdf.addImage(imgData, 'JPEG', 0, 0);
pdf.save("download.pdf");
```

Here the two zeroes are `padding` for the generated PDF document. You can change them as you want.

Also, you can modify the downloadable file name.

### Complete code

Here is the full code for a custom PDF downloader which takes two arguments:

 1. The root elements id as `rootElementId`

 2. Download filename `downloadFileName`

```js
import React from 'react';
import html2canvas from "html2canvas";
import { jsPDF } from "jspdf";

const GenericPdfDownloader = ({rootElementId , downloadFileName}) => {

    const downloadPdfDocument = () => {
        const input = document.getElementById(rootElementId);
        html2canvas(input)
            .then((canvas) => {
                const imgData = canvas.toDataURL('image/png');
                const pdf = new jsPDF();
                pdf.addImage(imgData, 'JPEG', 0, 0);
                pdf.save(`${downloadFileName}.pdf`);
            })
    }

    return <button onClick={downloadPdfDocument}>Download Pdf</button>

}

export default GenericPdfDownloader;
```

Now you can just place this component anywhere in your project like the following:

```js
import React from'react';
import GenericPdfDownloader from "./views/GenericPdfDownloader";

function App() {
  return (
    <>
        <GenericPdfDownloader 
          downloadFileName="CustomPdf" 
          rootElementId="testId" 
        />
        
        <div id="testId"> 
            This is A Downloadable Component 
        </div>
    </>
  );
}
```

export default App;
### Conclusion

There you go! Now you have your custom PDF downloader that can be used anywhere in your project. Thank you for reading!

**Have something to say?**

**Get in touch with me via [LinkedIn](https://www.linkedin.com/in/56faisal/) or my [Personal Website](https://www.mdfaisal.com/).**