react-pdf is a powerful and flexible library that allows developers to create dynamic, data-driven PDF documents using React components. It provides a declarative API, enabling you to define your PDF structure and content in a way very similar to how you build web interfaces with React, but instead of rendering to the HTML DOM, it renders to a PDF document tree.
Core Functionality:
At its heart, react-pdf provides a set of React components (e.g., <Document>, <Page>, <View>, <Text>, <Image>) that correspond to standard PDF elements. You compose these components to build your desired document layout and content. It leverages a styling system inspired by React Native, allowing you to use a StyleSheet API for applying CSS-like properties (including flexbox for layout, colors, fonts, etc.) to your PDF components.
Key Features:
* Declarative API: Build complex PDF layouts and content using familiar React component patterns.
* Styling with StyleSheet: Apply styles using an object-based CSS-in-JS approach, supporting common properties like flexbox for advanced layouts, font styling, colors, and more.
* Cross-platform: Generate PDFs both client-side in the browser (often displayed within an iframe using `PDFViewer`) and server-side using Node.js, making it highly versatile for various application architectures.
* Flexbox Layout: Offers robust layout capabilities with full flexbox support, simplifying the creation of responsive and complex page designs.
* Dynamic Content: Easily integrate data from your application state or props to generate personalized invoices, reports, certificates, or any other data-driven document.
* Custom Fonts and Images: Supports embedding custom TrueType fonts and rendering images within your PDFs.
Use Cases:
* Generating invoices, receipts, and order confirmations.
* Creating custom reports, certificates, and resumes dynamically.
* Providing print-ready versions of web content.
* Any scenario where sophisticated, styled PDF documents need to be created programmatically from a React application.
How it Works:
You define your PDF structure using react-pdf components within a regular React component. You apply styling using `StyleSheet.create()`. To display the PDF in the browser, you typically wrap your document component with `PDFViewer`. For server-side generation or to create a downloadable file, you can use methods like `pdf().toBlob()`, `pdf().toBuffer()`, or `pdf().toStream()` from the `@react-pdf/renderer` package.
Installation:
To get started, you can install the library using npm or yarn:
`npm install @react-pdf/renderer` or `yarn add @react-pdf/renderer`
Example Code
import React from 'react';
import { Page, Text, View, Document, StyleSheet, PDFViewer } from '@react-pdf/renderer';
// Create styles for your document
const styles = StyleSheet.create({
page: {
flexDirection: 'column',
backgroundColor: '#FAFAFA',
padding: 30,
fontFamily: 'Helvetica'
},
section: {
margin: 10,
padding: 10,
flexGrow: 1,
borderBottom: '1px solid #EEEEEE'
},
header: {
fontSize: 24,
marginBottom: 20,
textAlign: 'center',
color: '#333',
fontWeight: 'bold'
},
subHeader: {
fontSize: 16,
marginBottom: 10,
color: '#555'
},
text: {
fontSize: 12,
marginBottom: 5,
color: '#444'
},
strongText: {
fontSize: 14,
fontWeight: 'bold',
marginBottom: 5,
color: '#222'
},
tableRow: {
flexDirection: 'row',
borderBottom: '1px solid #EEE',
paddingVertical: 5,
},
tableCol: {
width: '33%',
textAlign: 'left',
paddingHorizontal: 5,
},
tableHeader: {
fontWeight: 'bold',
fontSize: 12,
color: '#333'
}
});
// Create Document Component
const MyInvoiceDocument = ({ invoiceData }) => (
<Document>
<Page size="A4" style={styles.page}>
<View style={styles.section}>
<Text style={styles.header}>Invoice</Text>
<Text style={styles.subHeader}>#{invoiceData.invoiceNumber}</Text>
<Text style={styles.text}>Date: {invoiceData.date}</Text>
</View>
<View style={styles.section}>
<Text style={styles.strongText}>Billed To:</Text>
<Text style={styles.text}>{invoiceData.customerName}</Text>
<Text style={styles.text}>{invoiceData.customerAddress.street}</Text>
<Text style={styles.text}>{invoiceData.customerAddress.city}, {invoiceData.customerAddress.zip}</Text>
</View>
<View style={{ ...styles.section, flexGrow: 2 }}>
<Text style={styles.strongText}>Items:</Text>
{/* Table Header */}
<View style={styles.tableRow}>
<View style={styles.tableCol}><Text style={styles.tableHeader}>Description</Text></View>
<View style={styles.tableCol}><Text style={styles.tableHeader}>Quantity</Text></View>
<View style={styles.tableCol}><Text style={styles.tableHeader}>Amount</Text></View>
</View>
{/* Table Rows */}
{invoiceData.items.map((item, index) => (
<View key={index} style={styles.tableRow}>
<View style={styles.tableCol}><Text style={styles.text}>{item.description}</Text></View>
<View style={styles.tableCol}><Text style={styles.text}>{item.quantity}</Text></View>
<View style={styles.tableCol}><Text style={styles.text}>${item.amount.toFixed(2)}</Text></View>
</View>
))}
</View>
<View style={styles.section}>
<Text style={{ ...styles.strongText, textAlign: 'right' }}>Subtotal: ${invoiceData.subtotal.toFixed(2)}</Text>
<Text style={{ ...styles.strongText, textAlign: 'right' }}>Tax ({invoiceData.taxRate * 100}%): ${invoiceData.taxAmount.toFixed(2)}</Text>
<Text style={{ ...styles.header, fontSize: 20, textAlign: 'right', marginTop: 10 }}>Total: ${invoiceData.total.toFixed(2)}</Text>
</View>
<View style={{ ...styles.section, marginTop: 'auto', borderBottom: 'none' }}>
<Text style={{ ...styles.text, textAlign: 'center', color: '#888' }}>
Thank you for your business! Please pay within 30 days.
</Text>
</View>
</Page>
</Document>
);
// Example usage in a React component to display the PDF in a viewer
function App() {
const exampleInvoiceData = {
invoiceNumber: '2023-10-001',
date: '2023-10-26',
customerName: 'Acme Corporation',
customerAddress: {
street: '123 Tech Park Ave',
city: 'Innoville',
zip: '98765'
},
items: [
{ description: 'Premium Software License', quantity: 1, amount: 299.99 },
{ description: 'Consulting Services (10 hrs)', quantity: 10, amount: 150.00 },
{ description: 'On-demand Support Package', quantity: 1, amount: 75.00 }
],
subtotal: 1874.99,
taxRate: 0.08,
taxAmount: 149.9992,
total: 2024.9892
};
// Calculate totals properly
exampleInvoiceData.subtotal = exampleInvoiceData.items.reduce((acc, item) => acc + (item.quantity * item.amount), 0);
exampleInvoiceData.taxAmount = exampleInvoiceData.subtotal * exampleInvoiceData.taxRate;
exampleInvoiceData.total = exampleInvoiceData.subtotal + exampleInvoiceData.taxAmount;
return (
<div style={{ height: '100vh', display: 'flex', flexDirection: 'column', padding: 20 }}>
<h1 style={{ textAlign: 'center', color: '#333' }}>React PDF Invoice Generator</h1>
<p style={{ textAlign: 'center', color: '#666', marginBottom: 20 }}>
Below is a dynamically generated PDF invoice using the react-pdf library.
</p>
<PDFViewer style={{ flex: 1, border: '1px solid #DDD', borderRadius: 8 }}>
<MyInvoiceDocument invoiceData={exampleInvoiceData} />
</PDFViewer>
</div>
);
}
export default App;








react-pdf