Introduction
Generating PDF based on different transaction is an important part of any retail applications. today we are going to show how can we generate PDF documents in React Native.
React Native has several good NPM libraries to generate PDF but articles and blogs are very few. So, I am letting you know how can you generate PDF in React Native using the very popular React Native PDF generation library called react-native-html-to-pdf
.
Create a React Native Project
npx react-native init MyRNPDF --template react-native-template-typescript
this command will create a new react native project
Folder Structure of a Newly created React Native Project
Change App.tsx file to print Hello World!
// App.tsx
import React from 'react';
import {StyleSheet, Text, View} from 'react-native';
function App() {
return (
<View style={styles.container}>
<Text style={styles.text}>Hello World</Text>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#aac',
alignItems: 'center',
justifyContent: 'center',
},
text: {
fontSize: 30,
color: '#fff',
},
});
export default App;
Build the Project and Run on an Emulator
npm run android
after successful build of the project you will see a Hello World!
message on your emulator/device screen:
Add Dependency Library for PDF generation
npm i react-native-html-to-pdf
we are using TypeScript in our project. So, we have to install below package too for type definition of react-native-html-to-pdf
library.
npm i @types/react-native-html-to-pdf
iOS only recommendation
React Native version >= 0.60.0, they have introduced autolinking so we do not required to link the library but need to install pods. but only for iOS we need install dependencies via pod
's:
cd ios && pod install && cd ..
Edit the File Path
Go directly to the source code in your
-
node modules
react-native-html-to-pdf
-
android
- src
- main
- java
- com
- christopherdro
- htmltopdf
In the convert()
function change this code block:
File path = (Environment.MEDIA_MOUNTED.equals(state)) ?
new File(mReactContext.getExternalFilesDir(null), options.getString(DIRECTORY)) :
new File(mReactContext.getFilesDir(), options.getString(DIRECTORY));
with below code block:
File path = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS), options.getString(DIRECTORY));
And that should change the file path to the appropriate location inside your emulator/device.
Permission for Android
We are accessing external storage so we need to add two permission in AndroidManifest.xml
file.
We are going to add the following permissions in the AndroidManifest.xml
- default
AndroidManifest.xml
file:
- Permission Code Block:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
Setting PDF generation
Update App.tsx
file as per your need with settings of react-native-html-to-pdf
library:
import React, {useState} from 'react';
import {Alert, Pressable, StyleSheet, Text, View} from 'react-native';
import RNHTMLtoPDF from 'react-native-html-to-pdf';
function App() {
const [isLoading, setIsLoading] = useState(false);
const [count, setCount] = useState(1);
const orderLines = [
{
id: 1,
product: 'Product 1',
quantity: 1,
price: '$10.00',
},
{
id: 2,
product: 'Product 2',
quantity: 2,
price: '$20.00',
},
{
id: 3,
product: 'Product 3',
quantity: 3,
price: '$30.00',
},
];
const generatePDF = async () => {
setIsLoading(true);
try {
const html = `
<html>
<head>
<style>
body {
font-family: 'Helvetica';
font-size: 12px;
}
header, footer {
height: 50px;
background-color: #fff;
color: #000;
display: flex;
justify-content: center;
padding: 0 20px;
}
table {
width: 100%;
border-collapse: collapse;
}
th, td {
border: 1px solid #000;
padding: 5px;
}
th {
background-color: #ccc;
}
</style>
</head>
<body>
<header>
<h1>Invoice for Order #${count}</h1>
</header>
<h1>Order Details</h1>
<table>
<tr>
<th>Order ID</th>
<td>${count}</td>
</tr>
<tr>
<th>Order Date</th>
<td>29-Jul-2022</td>
</tr>
<tr>
<th>Order Status</th>
<td>Completed</td>
</tr>
<tr>
<th>Order Total</th>
<td>$13232</td>
</tr>
</table>
<h1>Order Lines</h1>
<table>
<tr>
<th>Product ID</th>
<th>Product Name</th>
<th>Product Qty</th>
<th>Product Price</th>
</tr>
${orderLines
.map(
line => `
<tr>
<td>${line.id}</td>
<td>${line.product}</td>
<td>${line.quantity}</td>
<td>${line.price}</td>
</tr>
`,
)
.join('')}
</table>
<footer>
<p>Thank you for your business!</p>
</footer>
</body>
</html>
`;
const options = {
html,
fileName: `invoice_${count}`,
directory: 'Invoices',
};
const file = await RNHTMLtoPDF.convert(options);
Alert.alert('Success', `PDF saved to ${file.filePath}`);
setCount(count + 1);
setIsLoading(false);
} catch (error: any) {
Alert.alert('Error', error.message);
}
};
if (isLoading) {
return <Text>Generating PDF...</Text>;
}
return (
<View style={styles.container}>
<Pressable style={styles.button} onPress={() => generatePDF()}>
<Text style={styles.text}>Generate PDF</Text>
</Pressable>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#aac',
alignItems: 'center',
justifyContent: 'center',
},
text: {
fontSize: 24,
color: '#fff',
},
button: {
backgroundColor: '#6c8ee3',
padding: 15,
borderRadius: 10,
margin: 20,
},
});
export default App;
build your project again:
npm run android
Output
Visit the location which is showing in Success Alert and see generated PDF file.
- On Emulator:
On your real device you can see the file on your external device folder:
- Generate PDF on Real Device:
- Locate the generated PDF file:
Resources
- How to generate PDF from html in React Native
- Example to Make PDF in React Native from HTML Text
- Stack Overflow QA: How to print/save pdf in react native?
- Stack Overflow QA: pdf created by react native html to pdf is not showing in provided path
- The PDF file is NOT Created - Wrong filePath
- Stack Overflow QA: Pdf file not created using react-native-html-to-pdf
- React Native HTML to PDF
Top comments (3)
can you please tell for android how will we save this file in download
change the below code block to set your desired location:
Here I have chosen the
Documents
directory byEnvironment.DIRECTORY_DOCUMENTS