DEV Community

Cover image for Step-by-Step Guide to Generate and Download PDFs with React-PDF, FileSaver, and JSZip
Abhay Kumar
Abhay Kumar

Posted on

Step-by-Step Guide to Generate and Download PDFs with React-PDF, FileSaver, and JSZip

In this tutorial, we will explore how to use React-PDF, FileSaver, and JSZip to generate multiple PDFs and download them as a ZIP file. This is especially useful for applications where you need to generate custom reports or statements for different users and bundle them into a single compressed file for download.

Here’s a step-by-step guide on how to implement the solution.

Prerequisites
Before we start, make sure you have the following installed in your React project:

React - A JavaScript library for building user interfaces.

@react-pdf/renderer - To render PDFs in a React environment.

FileSaver - To enable file downloads.

JSZip - To compress multiple files into a ZIP format.

You can install the required dependencies with:

npm install @react-pdf/renderer file-saver jszip

Step 1: Create a Simple PDF Document with React-PDF

The first step is to create a basic PDF layout using the @react-pdf/renderer library. We define a simple component called StatementPdf, which will serve as our document template.

Here’s a basic PDF layout:

import React from 'react';
import { Page, Text, View, Document, StyleSheet } from '@react-pdf/renderer';

// Create styles
const styles = StyleSheet.create({
  page: {
    flexDirection: 'row',
    backgroundColor: '#E4E4E4'
  },
  section: {
    margin: 10,
    padding: 10,
    flexGrow: 1
  }
});

// Create Document Component
const StatementPdf = () => (
  <Document>
    <Page size="A4" style={styles.page}>
      <View style={styles.section}>
        <Text>Section #1</Text>
      </View>
      <View style={styles.section}>
        <Text>Section #2</Text>
      </View>
    </Page>
  </Document>
);

export default StatementPdf;

Enter fullscreen mode Exit fullscreen mode

In this document, we have a simple two-section layout on an A4-sized page.

Step 2: Generate Multiple PDFs

Now that we have the StatementPdf component, we can move on to generating multiple PDFs and zipping them together.

We will create a button that generates multiple PDFs when clicked, using the BlobProvider component from @react-pdf/renderer.

Here’s how to create and download multiple PDFs:

import { BlobProvider } from "@react-pdf/renderer";
import { saveAs } from "file-saver";
import JSZip from "jszip";
import ReactDOM from "react-dom";
import StatementPdf from "./components/StatementPdf";

const GeneratePdfButton = () => {
  const generatePdf = async () => {
    try {
      const pdfBlobs = await Promise.all(
        [2, 3, 4].map(() => generatePdfUrl())
      );
      await createAndDownloadZip(pdfBlobs);
    } catch (error) {
      console.error("Error generating PDFs:", error);
    }
  };

  const generatePdfUrl = (): Promise<Blob> => {
    return new Promise((resolve, reject) => {
      const pdfElement = (
        <BlobProvider document={<StatementPdf />}>
          {({ blob, loading, error }) => {
            if (!loading && !error && blob) {
              resolve(blob);
            } else if (error) {
              reject(error);
            }
            return null;
          }}
        </BlobProvider>
      );
      ReactDOM.render(pdfElement, document.createElement("div"));
    });
  };

  async function createAndDownloadZip(pdfBlobs: Blob[]) {
    const zip = new JSZip();
    const agent_name = "Abhay Kumar"; // This can be dynamic for different PDFs.

    for (let i = 0; i < pdfBlobs.length; i++) {
      const blob = pdfBlobs[i];
      zip.file(`${agent_name}-${i}.pdf`, blob);
    }

    const zipBlob = await zip.generateAsync({ type: "blob" });
    saveAs(zipBlob, "statements.zip");
  }

  return (
    <div>
      <button onClick={generatePdf}>Generate PDFs</button>
    </div>
  );
};

export default GeneratePdfButton;

Enter fullscreen mode Exit fullscreen mode

generatePdf: This function triggers the generation of multiple PDF files. It calls generatePdfUrl for each PDF you want to generate.

generatePdfUrl: A function that creates a Blob from the StatementPdf component using BlobProvider. Each Blob represents a PDF file.

createAndDownloadZip: This function compresses all the generated PDFs into a ZIP file using JSZip, then downloads it with FileSaver.

Step 3: Download the PDFs in a ZIP File

Once the PDFs are generated, they are compressed using the JSZip library. Each PDF is named based on the user's name (in this case, "Abhay Kumar"), and then downloaded as a .zip file.

In createAndDownloadZip, we loop through the pdfBlobs array, which contains all the generated PDFs, and add them to the ZIP. The ZIP file is then created and downloaded using the saveAs function from the FileSaver library.

Step 4: Display the PDF in a Viewer

You might also want to preview the generated PDF before downloading it. The @react-pdf/renderer library provides a convenient PDFViewer component for this purpose. Here's how you can add a viewer for the PDF:

      <div>
       <PDFViewer width={1200} height={600}>
          <StatementPdf />
        </PDFViewer>
      </div>
Enter fullscreen mode Exit fullscreen mode

Conclusion

In this tutorial, we’ve covered how to generate and download multiple PDFs in a React application. By using @react-pdf/renderer, JSZip, and file-saver, you can create a seamless experience for generating and downloading documents. Happy coding!

Feel free to customize the content and style of the blog post to better fit your needs! If you have any questions or need further assistance, just let me know.

🔗 Connect with me on LinkedIn:
Let's connect and discuss more about React, web development, and performance enhancement!

Follow me: Abhay Kumar

Top comments (0)