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