Did you know that nearly 90% of businesses report a significant increase in customer satisfaction when they provide downloadable content in a convenient PDF format? Generate PDFs in ReactJS has never been easier, thanks to the react-pdf library, which allows developers to seamlessly create dynamic and customizable PDF documents directly within their React applications.
To generate a PDF, you should implement a button that, when clicked, triggers the PDF creation and allows the user to either view or download the file. Begin by setting up this button within your React component.
Table of Contents
Key Takeaways
- User Demand: Understanding that a significant number of users prefer downloadable content in PDF format can drive better application design.
- Dynamic Content: ReactJS offers powerful capabilities to generate PDFs from dynamic content, making it easier to provide tailored information.
- Library Options: Familiarize yourself with popular libraries like jsPDF and React-PDF, which simplify the PDF generation process.
- Performance Considerations: Ensure that PDF generation does not hinder application performance by optimizing the generation process.
- Styling and Formatting: Utilize CSS for styling PDFs to maintain brand consistency and improve readability.
- Testing: Always test generated PDFs across different devices and browsers to ensure a consistent user experience.
- User Engagement: Offering downloadable PDFs can significantly enhance user engagement and satisfaction, leading to better retention rates.
- Accessibility: Consider accessibility features when generating PDFs to ensure all users can benefit from the content.
Integrate a button for downloading
npm i @react-pdf/renderer
Import the button into the desired page and render it within the HTML structure.
import { PDFDownloadLink } from "@react-pdf/renderer";
I have set placeholder content to dynamically load data
import { politicalData, basicInfo } from './Tested.jsx';
Create a separate file and include some placeholder data in it.
//Tested.jsx
export const politicalData = [
{
"heading": "General",
"qa": [
{
"q": "1. Political first question - ",
"a": "Not Exists",
"type": "list",
"prefixIcon": "https://cdn-icons-png.flaticon.com/128/1375/1375106.png",
"prefixIconSvg": "https://cdn-icons-png.flaticon.com/128/1829/1829586.png",
"valueIcon": "",
"place": "",
"options": []
},
{
"q": "2. Political second question - ",
"a": "District",
"type": "default",
"prefixIcon": "https://cdn-icons-png.flaticon.com/128/16/16410.png",
"prefixIconSvg": "https://cdn-icons-png.flaticon.com/128/1829/1829586.png",
"valueIcon": "",
"place": "",
"options": []
},
{
"q": "3. Political third question - ",
"a": "Town Planning Department of the State Government",
"type": "default",
"prefixIcon": "https://cdn-icons-png.flaticon.com/128/1375/1375106.png",
"prefixIconSvg": "https://cdn-icons-png.flaticon.com/128/1829/1829586.png",
"valueIcon": "",
"place": "",
"options": []
},
{
"q": "4. Political fourth question - ",
"a": "District",
"type": "default",
"prefixIcon": "https://cdn-icons-png.flaticon.com/128/16/16410.png",
"prefixIconSvg": "https://cdn-icons-png.flaticon.com/128/1829/1829586.png",
"valueIcon": "",
"place": "",
"options": []
},
{
"q": "5. Political fifth question - ",
"a": "District",
"type": "default",
"prefixIcon": "https://cdn-icons-png.flaticon.com/128/1375/1375106.png",
"prefixIconSvg": "https://cdn-icons-png.flaticon.com/128/1829/1829586.png",
"valueIcon": "",
"place": "",
"options": []
},
{
"q": "6. Political six question - ",
"a": "",
"type": "multiSelectionList",
"prefixIcon": "https://cdn-icons-png.flaticon.com/128/16/16410.png",
"prefixIconSvg": "https://cdn-icons-png.flaticon.com/128/1829/1829586.png",
"valueIcon": "https://cdn-icons-png.flaticon.com/128/1442/1442912.png",
"place": "pre",
"options": [
"Is this for testing",
"Yeah its a good plan",
"This is fine"
]
}
]
}];
export const basicInfo = {
"actor_id": "7878*******",
"actor_name": "Hansa Thakur",
"population_2011": "6,777",
"no_of_wards": "15",
"latest_population_year": 2024,
"latest_population": "10,128",
"state_name": "Himachal Pradesh",
"admin_officer_name": "Mr Hans Singh",
"admin_officer_designation": "Chief Municipal Officer",
"public_rep_name": "Mr Radhe Nag",
"public_rep_designation": "Chairperson",
"nodal_officer_name": "Mr Sanjay Pande",
"nodal_officer_designation": "Municipal Engineer",
"form_status": "Completed"
Establish a State to Manage PDF Downloads and Display Content Based on the Corresponding PDF Action
const [isDownload, setIsDownload] = useState(true); // Verifies whether the PDF is downloading
const [filename, setFilename] = useState("react-test.pdf"); // Specifies the file name
const [loader, setLoader] = useState(false); // Indicates whether the PDF is currently downloading…
When the button is clicked, the PDF should begin downloading; however, we need to inform the page that an action is taking place. To achieve this, we can manage our state to display a custom message on the button.
const handlePdf = () => {
setIsDownload(true);
setLoader(true);
setTimeout(() => {
setDisablePdf(false);
setLoader(false);
}, 2000);
};
CSS for buttons allows for extensive customization, enabling you to tailor your button’s appearance to suit your preferences.
.pdf-btn {
cursor: pointer;
display: flex;
justify-content: center;
font-size: 1rem; /* Base font size */
color: white;
font-weight: 500;
background-color: #0062BA;
border: 1px solid #0062BA; /* Border with specified color */
padding: 0.5rem; /* Padding equivalent to p-2 */
border-radius: 0.375rem; /* Rounded corners equivalent to rounded-md */
width: auto; /* Default width */
margin-left: auto; /* Left margin auto for alignment */
margin-right: 0; /* Right margin reset */
transition: all 0.7s ease-in-out; /* Transition effect */
align-items: center; /* Align items center in flex container */
}
/* Responsive adjustments */
@media (max-width: 640px) { /* Small screen breakpoint */
.pdf-btn {
margin-right: 0.75rem; /* Right margin for small screens */
}
}
@media (min-width: 1280px) { /* Extra-large screen breakpoint */
.pdf-btn {
margin-right: 0; /* Reset right margin for extra-large screens */
}
}
@media (min-width: 1536px) { /* 1xl breakpoint */
.pdf-btn {
margin-left: 0; /* Reset left margin for 1xl screens */
}
}
To optimize the code, we will create a separate PDF file where we will pass this in the document and write all the PDF content. This page will receive dynamic data. Therefore, ensure to import that file at the top.
import Pdf from "../Pdf";
Proceed to configure the button on the page
<PDFDownloadLink
className="pdf-btn"
fileName={filename}
onClick={handlePdf}
document={
<Pdf
download={isDownload}
basicData={basicInfo}//dynamic data
pData={politicalData} //dynamic data
/> }
>
{({ blob, url, loading, error }) => (
<>
<span>{loader ? "Loading documents..." : "Download Now"}</span>
</>
)}
</PDFDownloadLink>
We can incorporate Font Awesome icons or custom icons as needed. For instance, I referenced this image via a CDN and set it up in a dedicated file. To implement this, create a separate file named CDN.jsx.
export const img2 = 'https://cdn-icons-png.flaticon.com/128/3100/3100240.png';
export const agam ="https://png.pngtree.com/thumb_back/fh260/background/20241016/pngtree-large-orange-moon-is-in-the-sky-above-a-wave-image_16403128.jpg";
export const i_4 = 'https://t3.ftcdn.net/jpg/02/94/88/68/240_F_294886812_WDt5ec6COGuTGxnVuUVttrZWHg79F6Hb.jpg';
export const soul = 'https://images.pexels.com/photos/166277/pexels-photo-166277.jpeg';
export const i_1 ='https://cdn-icons-png.flaticon.com/128/17935/17935447.png';
export const i_3 = 'https://cdn-icons-png.flaticon.com/128/17992/17992957.png';
export const i_2 ='https://images.pexels.com/photos/164455/pexels-photo-164455.jpeg';
export const img1 = "https://images.pexels.com/photos/52718/angel-wings-love-white-52718.jpeg";
export const corner = 'https://image.shutterstock.com/image-vector/3d-fire-flame-icon-burning-260nw-2234372939.jpg';
export const dwnldbtn ='https://w7.pngwing.com/pngs/190/961/png-transparent-download-now-download-icon-download-button-download-logo-flat-icon-flat-logo-flat-image-button-flat-round.png'
Also Read:- React vs. React Native: Clash of Titans in the App Development Arena
Generate a PDF Featuring Dynamic Content.
For setting the font size in a PDF, we utilized the Poppins font library. You can, however, choose any library that suits your needs. I recommend Poppins because I’ve successfully used it in PDFs before. You can easily download the font files from the following link: https://fontlibrary.org/en/font/poppins#google_vignette and host them on your server or CDN.
//pdf.jsx
A PDF is a document format that enables us to control various components such as headers, footers, layout, and styling. Therefore, we must explicitly define and manage each of these elements
import {
Document,
Image,
Page,
StyleSheet,
Text,
View,
Font
} from "@react-pdf/renderer"; //call the element
You may specify the file path where your library is located.
import { CND_URL } from "../../Utils";
Import all the images from a separate file.
import { img1, img2, corner, soul, agam, i_1, i_2, i_3, i_4 } from './CDN';
Register font library.
Font.register({
family: 'Poppins', src: CND_URL + 'fonts/poppins/Poppins-Regular.ttf',
fonts: [
{ src: CND_URL + 'fonts/poppins/Poppins-ExtraBold.ttf', fontWeight: 'bold' },
{ src: CND_URL + 'fonts/poppins/Poppins-Light.ttf', fontWeight: 'normal' },
{ src: CND_URL + 'fonts/poppins/Poppins-Medium.ttf', fontWeight: 500 },
{ src: CND_URL + 'fonts/poppins/Poppins-Medium.ttf', fontWeight: 600 },
{ src: CND_URL + 'fonts/poppins/Poppins-bold.ttf', fontWeight: 800 },
{ src: CND_URL + 'fonts/poppins/Poppins-Italic.ttf', fontStyle: 'italic' },
]
});
Font.registerHyphenationCallback(word => (
[word]
));
const Pdf = ({
lastUpdated,
basicData,//get the data dynamically
pData,//get the data dynamically
}) => {
const styles = StyleSheet.create({ //set style of document
bottom: {
marginTop: 10,
height: '20px'
},
page: {
family: 'Poppins',
flexDirection: 'column',
backgroundColor: '#fff',
margin: 0,
paddingBottom: 50
},
section: {
position: 'relative',
margin: 0,
},
footer: {
position: 'absolute', // Fixed position at the bottom
bottom: 10,
height: 55, // Set the height of the footer
left: 20,
right: 20,
},
text1: {
fontSize: 22,
fontFamily: 'Poppins', fontWeight: 600,
color: '#000',
position: 'absolute', // Set position to absolute for precise text placement
top: '75%', // Adjust top to center vertically
left: '5%', // Adjust left to center horizontally
//transform: 'translate(-50%, -50%)', // Center the text
textAlign: 'left',
width: 280
},
text2: {
fontSize: 25,
fontFamily: 'Poppins', fontWeight: 'bold',
color: '#000',
position: 'absolute', // Set position to absolute for precise text placement
top: '75%', // Adjust top to center vertically
left: '5%', // Adjust left to center horizontally
//transform: 'translate(-50%, -50%)', // Center the text
textAlign: 'center',
},
text3: {
fontSize: 20,
color: '#686868',
fontFamily: 'Poppins', fontWeight: 500,
position: 'absolute', // Set position to absolute for precise text placement
top: '85%', // Adjust top to center vertically
left: '5%', // Adjust left to center horizontally
//transform: 'translate(-50%, -50%)', // Center the text width: '595', height: '100%',
textAlign: 'center',
},
text4: {
fontSize: 24,
fontFamily: 'Poppins', fontWeight: 600,
color: '#FE8402',
left: '5%',
position: 'absolute',
top: '90%',
},
power: {
paddingTop: 10,
fontSize: 11,
fontFamily: 'Poppins', fontWeight: 'normal',
color: '#000',
},
section2: {
flexDirection: 'row',
justifyContent: 'left', // Center content vertically
margin: 0
},
image: {
height: 750,
},
image2: {
width: 40,
height: 30,
paddingTop: 0
},
sectionContainer: {
margin: 20,
marginTop: 0,
position: 'relative',
fontFamily: 'Poppins'
},
row: {
flexDirection: 'column',
alignItems: 'left',
},
col: {
flexDirection: 'row', // Set to 'row' for left-to-right alignment
alignItems: 'left', // Align items vertically in the center
justifyContent: 'flex-end', // Align items to the right
marginTop: '-50'
},
corner: {
width: 33,
height: 35,
paddingTop: 10,
marginLeft: -10,
},
indicatorText: {
fontSize: 20,
fontFamily: 'Poppins', fontWeight: 600,
color: '#000', // Text color
},
indicatorBorder: {
marginTop: 2,
width: 50,
borderRadius: 5, // Set the border radius
borderWidth: 2, // Border width
borderStyle: 'solid', // Border style (solid, dashed, dotted, etc.)
borderColor: '#FF9211', // Border color
backgroundColor: '#FF9211',
},
logo: {
width: 140,
height: 50,
paddingRight: 10,
borderRightWidth: 1, // Border width
borderStyle: 'solid', // Border style (solid, dashed, dotted, etc.)
borderRightColor: '#000', // Border color
},
logo1: {
width: 140,
height: 50,
paddingLeft: 10,
},
tile: {
backgroundColor: '#0062BA',
paddingTop: 3,
paddingBottom: 3,
paddingLeft: 5,
color: '#fff',
fontSize: 13,
fontFamily: 'Poppins', fontWeight: 500,
/* height: 32,*/
borderTopRightRadius: 3,
borderBottomRightRadius: 3,
flex: 1,
},
headingP: {
display: "flex",
flexDirection: "row",
textAlign: 'left',
marginBottom: 5
},
headingPp: {
display: "flex",
flexDirection: "row",
textAlign: 'left',
paddingTop: 5
},
mBox: {
padding: 6,
backgroundColor: '#fff',
borderColor: '#C8C7C7',
borderWidth: 1,
borderRadius: 5,
paddingBottom: 5,
marginBottom: 5,
fontFamily: 'Poppins'
},
content: {
display: "flex",
flexDirection: "row",
fontFamily: 'Poppins'
},
contentM: {
color: '#000',
fontSize: 11,
width: '100%',
fontFamily: 'Poppins',
fontWeight: 500
},
contentImg: {
maxWidth: 15,
maxHeight: 12,
marginRight: 5,
marginTop: 3,
fontFamily: 'Poppins',
},
tableBottomIcon: {
width: 25,
height: 20,
paddingRight: 5,
},
dot1: { marginTop: 3, width: 6, height: 6, backgroundColor: '#936DFE' },
dot2: { marginTop: 3, width: 6, height: 6, backgroundColor: '#FF4E8E' },
dot3: { marginTop: 3, width: 6, height: 6, backgroundColor: '#5DBBFF' },
dot4: { marginTop: 3, width: 6, height: 6, backgroundColor: '#5FED52' },
label: { fontSize: 11, color: '#000', marginLeft: 5, fontFamily: 'Poppins', fontWeight: 500 },
value: { fontSize: 11, color: '#0062BA', fontFamily: 'Poppins', fontWeight: 600, marginLeft: 15 },
container: {
flexDirection: 'column',
alignItems: 'left',
justifyContent: 'left',
marginLeft: 10,
marginTop: 20,
},
sectionBox: { padding: 3, borderColor: '#CACACA', backgroundColor: '#F9F9F9', borderStyle: 'solid', borderWidth: 2, borderRadius: 5, width: 260, height: 280, marginBottom: 10 },
pagination: { textAlign: 'right', fontSize: 11, color: '#000', fontFamily: 'Poppins', fontWeight: 500, marginTop: 10 },
});
//You can create a function that capitalizes the first letter
function capitalizeText(sentence) {
if (sentence && sentence.length) {
// Split the sentence into words
const words = sentence.split(' ');
// Capitalize the first letter of each word
const capitalizedWords = words.map(word => {
// Capitalize the first letter and concatenate with the rest of the word
return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
});
// Join the words back into a sentence
const capitalizedSentence = capitalizedWords.join(' ');
return capitalizedSentence;
}
return sentence;
}
Keep the header separate so it can be called on every page. Use the View tag to define the layout and the Image tag to call the image. Additionally, keep all styles in a separate section.
const Header = ({ structure }) => (
<View fixed style={{ marginTop: 10 }}>
<Image style={styles.corner} src={corner} />
<View style={styles.row}>
<Text style={styles.indicatorText}>Indicators</Text>
<Text style={styles.indicatorBorder}></Text>
</View>
<View style={styles.col}>
<Image style={styles.logo} src={soul} />
<Image style={styles.logo1} src={agam} />
</View>
<View style={{ display: "flex", flexDirection: "row", marginTop: 5, marginBottom: 5 }}>
<Text style={{ textAlign: "left", color: '#0062BA', fontSize: 15, fontFamily: 'Poppins', fontWeight: 600 }}>{structure}</Text>
<Text style={{ textAlign: "right", flex: 1, color: '#0062BA', fontSize: 14, fontFamily: 'Poppins', fontWeight: 600 }}>{basicData?.actor_name}({basicData?.actor_id})</Text>
</View>
</View>
);
//Keep the footer section separate, just like the header, and call it on every page.
const Footer = ({ }) => (
<View style={styles.footer} fixed>
<View style={{
flexDirection: 'row', width: '100%', justifyContent: 'space-between'
}}>
< View style={styles.section2} >
<Text style={styles.power}>Powered By </Text>
<Image style={styles.image2} src={img2} />
</View>
<Text style={styles.pagination}
render={({ pageNumber, totalPages }) => (
`Page ${pageNumber} / ${totalPages}`
)}></Text>
</View>
</View>
);
Write code to create a page and include the header and footer on each page.
return (<>
{pData &&
<Document >
<Page size="A4" style={styles.page}>
<View style={styles.section}>
<Image style={styles.image} src={img1} />
<Text wrap={false} style={styles.text1}>{basicData?.actor_name}</Text>
<Text style={styles.text3}>{basicData?.actor_id}</Text>
<Text style={styles.text4}>{basicData?.state_name}</Text>
</View>
<View style={styles.footer}>
<View style={styles.section2}>
<Text style={styles.power}>Powered By </Text>
<Image style={styles.image2} src={img2} />
</View>
</View>
</Page>
<Page size="A4" style={styles.page}>
<View style={styles.sectionContainer}>
<View wrap={false} style={{ marginTop: 10 }}>
<Image style={styles.corner} src={corner} />
<View style={styles.row}>
<Text style={styles.indicatorText}>Actor Information</Text>
<Text style={styles.indicatorBorder}></Text>
</View>
<View style={styles.col}>
<Image style={styles.logo} src={soul} />
<Image style={styles.logo1} src={agam} />
</View>
<View style={{ display: "flex", flexDirection: "row", marginTop: 20, marginBottom: 10 }}>
{lastUpdated && <Text style={{ textAlign: "left", color: '#000', fontSize: 11, fontFamily: 'Poppins', fontWeight: 500 }}>Updated on: <Text style={{ color: '#0062BA' }}>{lastUpdated}</Text></Text>}
<Text style={{ textAlign: "right", flex: 1, color: '#0062BA', fontSize: 14, fontFamily: 'Poppins', fontWeight: 600 }}>{basicData?.actor_name}({basicData?.actor_id})</Text>
</View>
</View>
<View style={{ position: 'relative', display: 'flex', flexDirection: "row", justifyContent: 'space-between' }}>
{/***********SECTION 1***********/}
<View style={styles.sectionBox}>
<Text style={{ position: 'absolute', top: -5, left: 80, borderRadius: 5, borderColor: '#936DFE', backgroundColor: '#936DFE', borderWidth: 2, width: 100, height: 2, margin: '0 auto' }}></Text>
<View style={styles.headingPp}>
<Image style={styles.tableBottomIcon} src={i_1} />
<View style={{ flexDirection: 'column' }}>
<Text style={{ fontSize: 14, color: '#000', fontFamily: 'Poppins', fontWeight: 500 }}>Basic Details</Text>
</View>
</View>
<View style={styles.container}>
<View style={styles.headingP}>
<View style={styles.dot1} />
<View style={{ flexDirection: 'column' }}>
<Text style={styles.label}>Population</Text>
</View>
</View>
{basicData?.population_2011 && basicData?.population_2011 != 0 && <Text style={styles.value}>{basicData?.population_2011}</Text>}
{basicData?.population_2011 == 0 && <Text style={styles.value}> - </Text>}
</View>
<View style={styles.container}>
<View style={styles.headingP}>
<View style={styles.dot1} />
<Text style={styles.label}>Population {basicData?.latest_population_year && <Text>{basicData?.latest_population_year}</Text>}</Text>
</View>
{basicData?.latest_population && basicData?.latest_population != 0 && <Text style={styles.value}>{basicData?.latest_population}</Text>}
{basicData?.latest_population == 0 && <Text style={styles.value}> - </Text>}
</View>
<View style={styles.container}>
<View style={styles.headingP}>
<View style={styles.dot1} />
<Text style={styles.label}>District</Text>
</View>
<Text style={styles.value}>{basicData?.actor_name}</Text>
</View>
<View style={styles.container}>
<View style={styles.headingP}>
<View style={styles.dot1} />
<Text style={styles.label}>No. of Wards</Text>
</View>
{basicData?.no_of_wards != 'NULL' && <Text style={styles.value}>{basicData?.no_of_wards}</Text>}
{basicData?.no_of_wards == 'NULL' && <Text style={styles.value}>-</Text>}
</View>
</View>
{/**********************SECTION 2*****/}
<View style={styles.sectionBox}>
<Text style={{ position: 'absolute', top: -5, left: 80, borderRadius: 5, borderColor: '#FF4E8E', backgroundColor: '#FF4E8E', borderWidth: 2, width: 100, height: 2, margin: '0 auto' }}></Text>
<View style={styles.headingPp}>
<Image style={styles.tableBottomIcon} src={i_2} />
<View style={{ flexDirection: 'column' }}>
<Text style={{ fontSize: 14, color: '#000', fontFamily: 'Poppins', fontWeight: 500 }}>Authority</Text>
</View>
</View>
<View style={styles.container}>
<View style={styles.headingP}>
<View style={styles.dot2} />
<Text style={styles.label}>Name</Text>
</View>
<Text style={styles.value}>{capitalizeText(basicData?.admin_officer_name)}</Text>
</View>
<View style={styles.container}>
<View style={styles.headingP}>
<View style={styles.dot2} />
<Text style={styles.label}>Designation</Text>
</View>
<Text style={styles.value}>{capitalizeText(basicData?.admin_officer_designation)}</Text>
</View>
</View>
</View>
<View style={{ display: 'flex', flexDirection: "row", justifyContent: 'space-between' }}>
{/**********************SECTION 3*****/}
<View style={styles.sectionBox}>
<Text style={{ position: 'absolute', top: -5, left: 80, borderRadius: 5, borderColor: '#5DBBFF', backgroundColor: '#5DBBFF', borderWidth: 2, width: 100, height: 2, margin: '0 auto' }}></Text>
<View style={styles.headingPp}>
<Image style={styles.tableBottomIcon} src={i_3} />
<View style={{ flexDirection: 'column' }}>
<Text style={{ fontSize: 14, color: '#000', fontFamily: 'Poppins', fontWeight: 500 }}>Nodal Officer</Text>
</View>
</View>
<View style={styles.container}>
<View style={styles.headingP}>
<View style={styles.dot3} />
<Text style={styles.label}>Name</Text>
</View>
<Text style={styles.value}>{capitalizeText(basicData?.nodal_officer_name)}</Text>
</View>
<View style={styles.container}>
<View style={styles.headingP}>
<View style={styles.dot3} />
<Text style={styles.label}>Designation</Text>
</View>
<Text style={styles.value}>{capitalizeText(basicData?.nodal_officer_designation)}</Text>
</View>
</View>
{/**********************SECTION 4*****/}
<View style={styles.sectionBox}>
<Text style={{ position: 'absolute', top: -5, left: 80, borderRadius: 5, borderColor: '#5FED52', backgroundColor: '#5FED52', borderWidth: 2, width: 100, height: 2, margin: '0 auto' }}></Text>
<View style={styles.headingPp}>
<Image style={styles.tableBottomIcon} src={i_4} />
<View style={{ flexDirection: 'column' }}>
<Text style={{ fontSize: 14, color: '#000', fontFamily: 'Poppins', fontWeight: 500 }}>Representative</Text>
</View>
</View>
<View style={styles.container}>
<View style={styles.headingP}>
<View style={styles.dot4} />
<Text style={styles.label}>Name</Text>
</View>
<Text style={styles.value}>{capitalizeText(basicData?.public_rep_name)}</Text>
</View>
<View style={styles.container}>
<View style={styles.headingP}>
<View style={styles.dot4} />
<Text style={styles.label}>Designation</Text>
</View>
<Text style={styles.value}>{capitalizeText(basicData?.public_rep_designation)}</Text>
</View>
</View>
{/***************all section end***************/}
</View>
</View>
<Footer />
</Page>
{/*************Political page****************/}
<Page size="A4" style={styles.page}>
<View style={styles.sectionContainer}>
<Header structure={'Structure'} />
{pData && pData.map((items, index) => (
<View>
<View style={styles.headingP} wrap={false}>
<Text style={{ borderTopLeftRadius: 3, borderBottomLeftRadius: 3, width: 5, backgroundColor: '#26D8FF', }}></Text>
<Text style={styles.tile}>{items.heading}</Text>
</View>
{items && items['qa'] && items['qa'].map((item) => (
<View style={styles.mBox} wrap={false}>
<View style={styles.content}>
<Image style={styles.contentImg} src={item.prefixIcon} />
<Text style={styles.contentM}>{item.q} {item.a ? <Text style={{ paddingLeft: 3, color: '#0062BA', display: 'flex', gap: 1 }}>{item?.place == 'pre' && item.valueIcon == '\u20b9' && <Text>{item.a}</Text>} {item?.place == 'pre' && item.valueIcon != '\u20b9' && <Text>{item.valueIcon + item.a}</Text>}{item.place == 'post' && item.valueIcon && item.valueIcon == '%' && <Text>{item.a + item.valueIcon}</Text>}{item?.place == 'post' && item.valueIcon && item.valueIcon != '%' && <Text>{item.a} {item.valueIcon}</Text>} {(!item.valueIcon || item.valueIcon == '') && <Text>{item.a}</Text>}</Text> : ''}</Text>
</View>
{
item.type != 'default' && item.type !== 'multiSelectionList' && item.options &&
<View style={styles.content}>
<View style={{ paddingLeft: 20, color: '#000', fontWeight: 500, flexDirection: 'column', gap: 1, fontSize: 11, fontFamily: 'Poppins', fontStyle: 'italic' }}>
{item.options.map((nexted) => (
<Text style={{ paddingLeft: 10, color: '#000', display: 'flex', gap: 1, fontFamily: 'Poppins', fontStyle: 'italic' }}>{nexted.label} {nexted?.place == 'pre' && nexted.value && <Text style={{ color: '#0062BA', fontFamily: 'Poppins', fontStyle: 'italic' }}>{nexted.valueIcon != '\u20b9' && nexted.valueIcon}</Text>}{nexted.type == 'url' && nexted.value && <Text style={{ textDecoration: 'underline', color: '#0062BA', fontFamily: 'Poppins', fontStyle: 'italic' }} >{nexted.value}</Text>}{(!nexted.type || nexted.type != 'url') && nexted.value && <Text style={{ color: '#0062BA', fontFamily: 'Poppins', fontStyle: 'italic' }}>{nexted.value}</Text>}{nexted?.place == 'post' && nexted.value && <Text style={{ color: '#0062BA' }}>{nexted.valueIcon && nexted.valueIcon != '%' && <Text> </Text>}{nexted.valueIcon}</Text>}</Text>
))}
</View>
</View>
}
{item.type == 'multiSelectionList' && item.options &&
<View style={styles.content}>
<View style={{ paddingLeft: 15, color: '#17CD1F', flexDirection: 'column', gap: 1, fontSize: 11, fontFamily: 'Poppins', fontStyle: 'italic' }}>
{item.options.map((nexted) => (
<Text style={{ paddingLeft: 5, color: '#000', display: 'flex', gap: 1, fontFamily: 'Poppins', fontStyle: 'italic' }}> <Text style={{ color: '#0062BA', fontFamily: 'Poppins', fontStyle: 'italic', fontWeight: 500 }}>{nexted}</Text></Text>
))}
</View>
</View>
}
</View>
))}
</View>
))}
</View>
<Footer />
</Page>
{/*************End of political page****************/}
</Document>}
</>);
};
export default Pdf;
Output
Cloud Solutions by HashStudioz: Scalable PDF Generation for Dynamic Content
At HashStudioz, our Cloud Solutions offer robust cloud-based PDF generation services designed to meet the needs of businesses seeking scalable and efficient document creation. Our service is particularly beneficial for applications built with dynamic content, ensuring that users can generate, store, and retrieve documents seamlessly.
Key Features of Our Cloud PDF Generation Services:
- Scalability: Our cloud infrastructure is built to scale with your business requirements. Whether you need to generate a few PDFs or thousands, HashStudioz ensures consistent performance under varying demands.
- Efficient Document Creation: Leveraging cloud computing resources allows for rapid and efficient PDF generation. Users can create documents on-demand, pulling real-time data from your ReactJS application for accurate and up-to-date results.
- Secure Storage: Generated PDFs are stored securely in the cloud, providing easy access and retrieval from anywhere. This eliminates the limitations of local storage while ensuring document security.
- Collaborative Access: Our solutions facilitate collaborative efforts, enabling teams to share and access documents easily, streamlining workflows across the organization.
- Integration with Existing Systems: HashStudioz ensures seamless integration of our cloud PDF generation services with your current applications and workflows, enhancing functionality without a complete system overhaul.
- Automatic Updates: As your application evolves, our cloud solutions allow for quick updates to PDF templates and generation logic, keeping your documents aligned with the latest changes.
- Cost Efficiency: Utilizing our cloud infrastructure can lead to significant cost savings by reducing the need for extensive on-premises hardware and maintenance. You pay only for the resources you use, providing a flexible and budget-friendly solution.
Conclusion
Generating PDFs for dynamic content in ReactJS is not only feasible but also essential for enhancing user experience and engagement. By leveraging powerful libraries like jsPDF and React-PDF, developers can seamlessly transform their applications to meet the growing demand for downloadable content. As businesses continue to prioritize user-friendly features, mastering PDF generation can provide a competitive edge. Don’t let your application fall behind—embrace the power of PDFs and watch your user satisfaction soar!