DEV Community

Michael Burrows
Michael Burrows

Posted on • Originally published at w3collective.com

Exporting a React component to a PDF file on click

In this tutorial we’ll covering the process of exporting a React component to a PDF file.

We’ll be using jsPDF to generate the PDF which can be installed by running:

npm install jspdf

For the purposes of this tutorial we’ll create a simple “shipping label” component which will contain an address and barcode image. Here’s what the basic structure of our ShippingLabel.js component will look like:

import { jsPDF } from "jspdf";
import Barcode from "./barcode.png";

const ShippingLabel = () => {    
    const createPDF = async () => {
        // TODO
    }; 
    return (<>{/* TODO */}</>);
};

export default ShippingLabel;
Enter fullscreen mode Exit fullscreen mode

We’ve used an asynchronous function here so we can use the await keyword which will allow us to wait until all the HTML markup has been captured from the component before moving onto the generation of the PDF document.

Now let’s complete the return statement with the HTML markup that we’ll export to the PDF along with a button that’ll generate the PDF when clicked:

return (
  <div className="shipping">
    <h1>Download Shipping Label</h1>
    <p>Nihil quam soluta sed enim aut omnis voluptatem reprehenderit.</p>
    <div id="pdf">
        <p>TO: John Citizen</p>
        <p>123 Random Street</p>
        <p>Oak Creek, Colorado (CO), 80467</p>
        <p><img src={Barcode} alt="Barcode" /></p>
    </div>
    <button onClick={createPDF} type="button">Download</button>
  </div>
);
Enter fullscreen mode Exit fullscreen mode

Anything outside <div id="pdf"> will not be exported to the PDF.

We can now complete the createPDF function:

const createPDF = async () => {
  const pdf = new jsPDF("portrait", "pt", "a4");
  const data = await document.querySelector("#pdf");
  pdf.html(data).then(() => {
    pdf.save("shipping_label.pdf");
  });
};
Enter fullscreen mode Exit fullscreen mode

This creates a new jsPDF object and set’s the orientation (portrait), base unit to be used when coordinates are specified (pt), and the document size (a4). You can view the full range of options available in the official documentation here.

If you test what we’ve created so far you’ll notice CSS from external style sheets are not captured in the PDF. If you do want external CSS styles to appear in the PDF you’ll either need to use CSS in JS or another library called html2canvas which captures the HTML as image before exporting to PDF.

Let modify our component to capture external CSS by first installing html2canvas:

npm install html2canvas

And then import into our component:

import html2canvas from "html2canvas";
import { jsPDF } from "jspdf";
import Barcode from "./barcode.png";
Enter fullscreen mode Exit fullscreen mode

We can now update the createPDF function to capture the HTML:

const createPDF = async () => {   
  const pdf = new jsPDF("portrait", "pt", "a4"); 
  const data = await html2canvas(document.querySelector("#pdf"));
  const img = data.toDataURL("image/png");  
  const imgProperties = pdf.getImageProperties(img);
  const pdfWidth = pdf.internal.pageSize.getWidth();
  const pdfHeight = (imgProperties.height * pdfWidth) / imgProperties.width;
  pdf.addImage(img, "PNG", 0, 0, pdfWidth, pdfHeight);
  pdf.save("shipping_label.pdf");
};
Enter fullscreen mode Exit fullscreen mode

Now when you test the functionality you’ll see any styles from external CSS files are captured in the PDF.

That’s all for this tutorial. You should now have an understanding of how jsPDF & html2canvas can be used to export a React component to a PDF file. The full source code for the component is available on GitHub.

Top comments (0)