I'm using PDFDownloadLink
from the react-pdf
package to generate a PDF on the fly in my application and allow the user to download a report based on data being passed to the component that generates the PDF document. However, there are more than 400 pages that need to be rendered in this PDF, and this operation blocks the main thread for a few seconds. Is there any way to make this operation asynchronous, so the rest of the application will continue to function while the PDF is being generated? Also I would like to be able to cache the results, since the data being passed to the component can come from about 8 different arrays of data, which don't change very much, so switching between these arrays I would rather not to have to render the PDF all over again if the PDF for that given array has already been generated once before... I'm guessing the blob data needs to be stored somewhere, perhaps localStorage?
import { Page, Text, View, Document, StyleSheet, PDFDownloadLink } from '@react-pdf/renderer'
const App = () => {
const condition = "firstCondition";
const filteredRowData = rowData.filter(a => a.condition = condition);
return (
<PDFDownloadLink
document={<PDF_REPORT_Document rowData={filteredRowData} />}
fileName={"PDF_REPORT.pdf"}
style={{color:'white'}}
>{({ blob, url, loading, error }) =>
loading ? "Report loading..." : "Report ready to download"
}</PDFDownloadLink>
);
}
const PDF_REPORT_Document = (props) => {
const { rowData } = props;
const styles = StyleSheet.create({
page: {
flexDirection: 'column',
backgroundColor: '#E4E4E4'
},
section: {
margin: 10,
padding: 10,
flexGrow: 1
}
});
return(
<Document>
{rowData.map((row,index) =>
<Page size="A4" style={styles.page} key={index}>
<View style={styles.section}>
<Text>Name: {row.FULLNAME}</Text>
</View>
</Page>
)}
</Document>
);
}
I finally found the answer to this in an issue on github which addresses this exact problem:
Is your feature request related to a problem? Please describe. It is an improvement. At the moment, if you use 'PDFDownloadLink' the PDF is being generated as the component loads.
Describe the solution you'd like It is not mandatory, but having multiple heavy PDFs ready to be downloaded wouldn't be the best approach since not every user will need it.
Describe alternatives you've considered I've used
pdf()
function to generate the blob andfile-saver
lib to download it:import { saveAs } from 'file-saver'; import { pdf } from '@react-pdf/renderer'; import PdfDocument from '../PdfDocument'; const generatePdfDocument = async (documentData,fileName) => { const blob = await pdf(( <PdfDocument title='My PDF' pdfDocumentData={documentData} /> )).toBlob(); saveAs(blob, fileName); }; export default generatePdfDocument;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With