Generating a PDF in React
Below is a minimal approach to generating PDFs in React applications: 1. Install the Dependencies npm install html2canvas jspdf 2. A Hidden PDF Component 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 import React from "react"; import { format } from "date-fns"; interface PDFReportProps { reportDate: Date; totalItems: number; } const PDFReport = React.forwardRef<HTMLDivElement, PDFReportProps>( (props, ref) => { const { reportDate, totalItems } = props; return ( <div ref={ref} style={{ position: "absolute", top: "-9999px", left: "-9999px", width: "800px", }} > <h1>Report - {format(reportDate, "MMMM yyyy")}</h1> {totalItems > 0 ? ( <p>Your main PDF content goes here.</p> ) : ( <p>No data available this month.</p> )} </div> ); } ); PDFReport.displayName = "PDFReport"; export default PDFReport; We use React.forwardRef so that this component’s DOM node is accessible elsewhere. Position it off-screen (top: -9999px) so it never appears in the rendered UI. 3. A Button & Utility to Generate the PDF 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 import React from "react"; import html2canvas from "html2canvas"; import jsPDF from "jspdf"; interface PDFGeneratorProps { onGenerate: () => void; } const PDFGenerator: React.FC<PDFGeneratorProps> = ({ onGenerate }) => ( <button onClick={onGenerate}>Download PDF</button> ); export default PDFGenerator; export const generatePDF = async ( reportRef: React.RefObject<HTMLDivElement>, reportTitle: string ): Promise<void> => { if (!reportRef.current) return; try { const canvas = await html2canvas(reportRef.current, { scale: 2, useCORS: true, backgroundColor: "#ffffff", }); const imgData = canvas.toDataURL("image/png"); const pdf = new jsPDF({ orientation: "portrait", unit: "mm", format: "a4", }); const pdfWidth = pdf.internal.pageSize.getWidth(); const pdfHeight = pdf.internal.pageSize.getHeight(); const imgWidth = canvas.width; const imgHeight = canvas.height; const ratio = Math.min(pdfWidth / imgWidth, pdfHeight / imgHeight); const imgPdfWidth = imgWidth * ratio; const imgPdfHeight = imgHeight * ratio; const xOffset = (pdfWidth - imgPdfWidth) / 2; pdf.addImage(imgData, "PNG", xOffset, 0, imgPdfWidth, imgPdfHeight); pdf.save(`${reportTitle}.pdf`); } catch (err) { console.error("Error generating PDF:", err); } }; Key Points: ...