How to create PDF in React JS Next JS Vite Js
In my current project, I need my application to make PDF files from data, such as reports or certificates. I'm using a popular library called pdf-renderer in my React app to easily generate and download PDF documents. This helps me achieve my project's goal with minimal effort.
Getting started
To get started with react-pdf install the package from the command line,
yarn add @react-pdf/renderer or npm install @react-pdf/renderer or pnpm install @react-pdf/renderer
The basic thing to render a pdf is knowing these important components that pdf-render provides us.
Document: It is the root of the PDF, like a<html>tag.Page: This component represents a single page inside our documents, but we can use multiple inside theDocumentText: This component for displaying text, supports nesting of links or other textsView: The most fundamental component for building a UI, is the design to be nested inside other views, which you can use as a<div>tag.Image: A component that can be used for displaying images, keep in mind that you should not miss out on the source object.
Rendering your first PDF on DOM
import { PDFViewer } from '@react-pdf/renderer';
import MyDocument from './MyDocument'
const App = () => (
<PDFViewer width={1200} height={1200} showToolbar={false}>
<MyDocument />
</PDFViewer>
);
export default App
Get the Complete Invoice Code in React JS
import { Document, Page, Text, View, StyleSheet, Font } from '@react-pdf/renderer';
const borderColor = '#000'
Font.register({
family: 'Oswald',
src: 'https://fonts.gstatic.com/s/oswald/v13/Y_TKV6o8WovbUd3m_X9aAA.ttf',
fontWeight: 700
});
const styles = StyleSheet.create({
page: {
flexDirection: 'row',
// backgroundColor: '#f6fbff',
// height: 1000,
// width: 1200,
padding:20,
},
container:{
borderWidth: 2,
borderColor: borderColor,
},
invoice: {
width: 600,
marginTop: 5,
display: 'flex',
fontSize: 10,
flexDirection: 'row',
justifyContent: 'space-around',
},
title: {
marginTop: 10,
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
flexDirection: 'column',
fontFamily: 'Times-Roman'
},
busenessName: {
marginBottom: 5,
textAlign: 'center',
fontSize: 26,
},
businessAddress: {
fontSize: 12,
marginBottom: 10
},
customerInfo: {
borderTopWidth: 2,
borderBottomWidth: 2,
display: 'flex',
justifyContent: 'space-between',
flexDirection: 'row',
flexWrap: 'wrap',
fontSize: 11,
fontWeight: 'bold'
},
name: {
margin: 3
},
basicInfo: {
padding: 5,
},
invoiceNo: {
borderLeftWidth: 2,
padding: 5,
},
billContanier: {
flexDirection: 'row',
alignItems: 'start',
textAlign: 'start',
},
billadd:{
width: '65%',
borderRightColor: borderColor,
borderRightWidth: 2,
borderTopWidth: 2,
fontSize: 11,
textAlign: 'justify',
fontWeight: 'heavy',
padding: 4,
},
shippAdd: {
borderTopWidth: 2,
borderRightColor: borderColor,
width: '35%',
fontSize: 11,
textAlign: 'justify',
padding: 4,
},
itemContainer: {
display: 'flex',
flexDirection: 'row',
borderBottomWidth: 2
},
sNo: {
width: '10%',
borderRightColor: borderColor,
borderTopWidth: 2,
fontSize: 12,
textAlign: 'justify',
fontWeight: 'heavy',
padding: 4,
},
itemName: {
width: '70%',
borderRightColor: borderColor,
borderRightWidth: 2,
borderTopWidth: 2,
borderLeftWidth: 2,
fontSize: 12,
textAlign: 'center',
padding: 4,
},
itemPrice: {
width: '20%',
borderRightColor: borderColor,
borderTopWidth: 2,
fontSize: 12,
textAlign: 'center',
fontWeight: 'heavy',
padding: 4,
},
items: {
display: 'flex',
flexDirection: 'row',
alignItems: 'center'
},
sNodynamic: {
width: '10%',
borderRightColor: borderColor,
fontSize: 11,
textAlign: 'center',
fontWeight: 'heavy',
padding: 2,
},
itemNamedynamic: {
width: '70%',
borderRightColor: borderColor,
borderRightWidth: 2,
borderLeftWidth: 2,
fontSize: 11,
textAlign: 'justify',
padding: 4,
},
itemPricedynamic: {
width: '20%',
borderRightColor: borderColor,
fontSize: 11,
textAlign: 'center',
fontWeight: 'heavy',
padding: 2,
},
termsContanier: {
display: 'flex',
flexDirection: 'row',
borderTopWidth: 2,
borderBottomWidth: 2,
alignItems: 'center'
},
termsRow: {
width: '65%',
// borderRightColor: borderColor,
borderRightWidth: 2,
fontSize: 11,
textAlign: 'justify',
padding: 4,
},
priceRow: {
width: '35%',
fontSize: 11,
textAlign: 'justify',
},
subtotal: {
display: 'flex',
flexDirection: 'row',
alignItems: 'start',
textAlign: 'start',
},
gstMgmt: {
width: '43%',
borderRightColor: borderColor,
borderRightWidth: 2,
fontSize: 11,
textAlign: 'center',
fontWeight: 'heavy',
},
priceMgmt: {
borderRightColor: borderColor,
width: '57%',
fontSize: 11,
textAlign: 'center',
},
bordrerdesign:{
borderBottomWidth:2,
padding:8
},
paddingdesign:{
padding:2
},
termHeading: {
marginTop: 50,
marginBottom: 50,
marginLeft:20,
display: 'flex',
justifyContent: 'center',
flexDirection: 'column',
},
footer: {
height: 20,
textAlign: 'center',
justifyContent:'center',
marginLeft:20
},
termCondition: {
flexDirection: "row",
alignItems: "center",
minHeight: 24,
height: "auto",
fontStyle: "bold",
fontSize:12,
flexWrap: "wrap",
marginTop: 1,
},
});
const MyDocument = () => (
<Document>
<Page size="A4" style={styles.page}>
<View style={styles.container}>
<View style={styles.invoice}>
<View> <Text>GSTIN:09BBMPG0319L2ZI</Text></View>
<View> <Text>TAX INVOICE</Text></View>
<View>
<Text>Mob:+91-8188088875</Text>
<Text style={styles.name}>INVOICE No.: 20</Text>
</View>
</View>
<View style={styles.title}>
<Text style={styles.busenessName}>Yagya Event</Text>
<Text style={styles.businessAddress}>Business Address:Gomati Nagar, Lucknow</Text>
</View>
<View style={styles.billContanier}>
<Text style={styles.billadd}>Bill To</Text>
<Text style={styles.shippAdd}>Shipp To</Text>
</View>
<View style={styles.billContanier} >
<View style={styles.billadd} >
<Text style={styles.name}>Name: Mr. Aniruddh Varshney</Text>
<Text style={styles.name}>Address : Gomati Nagar, Lucknow </Text>
<Text style={styles.name}>GST no.: 09AAICT1512H1ZG</Text>
<Text style={styles.name}>Mobile No.: +91 9023606749</Text>
</View>
<View style={styles.shippAdd}>
<Text style={styles.name}>Shipping Address:Delhi</Text>
<Text style={styles.name}>Delivery Date:06-01-2024</Text>
<Text style={styles.name}>Invoice Date.: 06-01-2024</Text>
</View>
</View>
<View style={styles.itemContainer}>
<Text style={styles.sNo}>S.No</Text>
<Text style={styles.itemName}>Title</Text>
<Text style={styles.itemPrice}>Price</Text>
</View>
<View style={styles.row}>
<View style={styles.items}>
<Text style={styles.sNodynamic}>01</Text>
<View style={styles.itemNamedynamic}>
<Text>Lenovo Thinkpad</Text>
<Text>All disputes subject to lucknow jurisdiction</Text>
</View>
<Text style={styles.itemPricedynamic}>85678</Text>
</View>
<View style={styles.items}>
<Text style={styles.sNodynamic}>01</Text>
<View style={styles.itemNamedynamic}>
<Text>Lenovo Thinkpad</Text>
<Text>All disputes subject to lucknow jurisdiction</Text>
</View>
<Text style={styles.itemPricedynamic}>85678</Text>
</View>
<View style={styles.items}>
<Text style={styles.sNodynamic}>01</Text>
<View style={styles.itemNamedynamic}>
<Text>Lenovo Thinkpad</Text>
<Text>All disputes subject to lucknow jurisdiction</Text>
</View>
<Text style={styles.itemPricedynamic}>85678</Text>
</View>
<View style={styles.items}>
<Text style={styles.sNodynamic}>01</Text>
<View style={styles.itemNamedynamic}>
<Text>Lenovo Thinkpad</Text>
<Text>All disputes subject to lucknow jurisdiction</Text>
</View>
<Text style={styles.itemPricedynamic}>85678</Text>
</View>
<View style={styles.items}>
<Text style={styles.sNodynamic}>02</Text>
<View style={styles.itemNamedynamic}>
<Text>Lenovo Thinkpad</Text>
<Text>AMD, 12 GB Ram, 128 SSD</Text>
</View>
<Text style={styles.itemPricedynamic}>85678</Text>
</View>
<View style={styles.items}>
<Text style={styles.sNodynamic}>03</Text>
<View style={styles.itemNamedynamic}>
<Text>Boat SmartWatch</Text>
<Text>4h battery backup, social media</Text>
</View>
<Text style={styles.itemPricedynamic}>85678</Text>
</View>
</View>
<View style={styles.termsContanier}>
<View style={styles.termsRow}>
<View>
<Text style={styles.paddingdesign}>Bank Details:</Text>
<Text style={styles.paddingdesign}>Bank Name : BANDHAN BANK</Text>
<Text style={styles.paddingdesign}>Branch : GOMTINAGAR,LUCKNOW</Text>
<Text style={styles.paddingdesign}>Account No : 10210009229916</Text>
<Text style={styles.paddingdesign}>Bank IFSC : BDBL0001908</Text>
<Text style={styles.paddingdesign}>Bank IFSC : BDBL0001908</Text>
</View>
</View>
<View style={styles.priceRow}>
<View style={styles.subtotal}>
<View style={styles.gstMgmt}>
<Text style={styles.bordrerdesign}>SubTotal</Text>
<Text style={styles.bordrerdesign}>CGST</Text>
<Text style={styles.bordrerdesign}>SGST</Text>
<Text style={styles.paddingdesign}>Total</Text>
</View>
<View style={styles.priceMgmt}>
<Text style={styles.bordrerdesign}>180000</Text>
<Text style={styles.bordrerdesign}>600</Text>
<Text style={styles.bordrerdesign}>600</Text>
<Text style={styles.paddingdesign}>20000/-</Text>
</View>
</View>
</View>
</View>
<View style={styles.termHeading}>
<Text>Terms & Conditions</Text>
</View>
<View style={styles.footer}>
<View style={styles.termCondition}>
<Text>All amounts are in INR. Please make payments in the specified currency</Text>
</View>
<View style={styles.termCondition}>
<Text style={styles.termCondition}>We accept payments via UPI, Cash, Net Banking, Debit Card</Text>
</View>
<View style={styles.termCondition}>
<Text >Cancellations must be requested in writing within 7 days of the invoice date. Refunds will be issued
</Text>
</View>
<View style={styles.termCondition}>
<Text>All amounts are in INR. Please make payments in the specified currency</Text>
</View>
</View>
</View>
</Page>
</Document>
);
export default MyDocument
If I have to point out there is styling limitations for example there is overflow provides only hidden property and other do not support, display only supports flex and none.
