Hey guys welcome to AV Coding
Today, we will delve into how to integrate the @react-pdf/renderer library into our React code.
NPM REPO: https://www.npmjs.com/package/@react-pdf/renderer
React-pdf Doc: https://v3.react-pdf.org/
PDFkit Doc: https://pdfkit.org/
npm install @react-pdf/renderer --save
App.js
import './App.css';
import { ReactPdfDocument } from './ReactPdf';
import ReactPdfHook from './ReactPdfHook';
import { pdf, BlobProvider, PDFViewer, PDFDownloadLink } from '@react-pdf/renderer';
function App() {
const blob = pdf(<ReactPdfDocument />).toBlob()
blob.then((data)=> console.log("BLOB", data));
return (
<div className="App">
<PDFDownloadLink
document={<ReactPdfDocument />}
fileName="somename.pdf"
>
{({ blob, url, loading, error }) =>
loading ? 'Loading document...' : 'Download now!'
}
</PDFDownloadLink>
<br />
<BlobProvider document={<ReactPdfDocument />}>
{({ blob, url, loading, error }) => {
console.log('blob', blob);
console.log('url', url);
console.log('loading', loading);
console.log('error', error);
return <div>There's something going on on the fly</div>;
}}
</BlobProvider>
<br />
<PDFViewer
showToolbar
width={'100%'}
style={{ height: '100vh' }}
>
<ReactPdfDocument />
</PDFViewer>
<br />
<ReactPdfHook />
</div>
);
}
export default App;
ReactPdf.js
import React from 'react';
import { Image, Note, Canvas, Font, Link, Page, Text, View, Document, StyleSheet } from '@react-pdf/renderer';
// Create styles
const styles = StyleSheet.create({
page: {
flexDirection: 'row',
backgroundColor: '#E4E4E4',
minHeight: '100vh',
minWidth: '100vw'
},
section: {
margin: 10,
padding: 10,
flexGrow: 1
}
});
const TestRender = (output) => {
console.log("TestRender", output)
};
const hyphenationCallback = (word) => {
return word.replace(/([aeiouy])(?=[^aeiouy])/gi, '$1-').split('-');
};
const drawRectangle = (canvas, width, height) => {
console.log("Canvas ", canvas);
console.log("width ", width);
console.log("height ", height);
canvas.fillColor('blue');
canvas.text('Here is a link!', 100, 100);
};
Font.registerHyphenationCallback(hyphenationCallback);
// Create Document Component
export const ReactPdfDocument = () => {
return (
<Document
title='TestTitle'
author='TestAuthor'
subject='TestSubject'
keywords='TestKeywords'
creator='TestCreator'
producer='TestProducer'
pdfVersion='TestVersion'
language='TestLanguage'
pageMode='fullScreen'
pageLayout='singlePage'
onRender={TestRender}
>
<Page size="A4" style={styles.page} wrap={true}
orientation='landscape'>
<View style={styles.section}>
<Link src='#Section1'>
Section
</Link>
</View>
<View style={styles.section}>
<Text>Section 2</Text>
</View>
</Page>
<Page debug size="A4" style={styles.page} wrap={true}
orientation='portrait'>
<View style={styles.section}>
<Link src='#Section1'>
Section
</Link>
</View>
<View style={styles.section}>
<Text>Section 2</Text>
</View>
</Page>
<Page dpi={100}>
<View id='Section1' orphans={2} widows={2} minPresenceAhead={10}>
<Text>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</Text>
</View>
</Page>
<Page bookmark="Harry Potter and the Philosopher's Stone">
<Text bookmark={{ title: "Chapter 1: The Boy Who Lived", fit: true }}>
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</Text>
<Text render={({ pageNumber, totalPages, subPageNumber, subPageTotalPages }) => (
`\n\n${pageNumber} / ${totalPages} \n` +
`${subPageNumber} / ${subPageTotalPages}`
)} fixed />
</Page>
<Page>
<Note fixed>
<Text>This is a note annotation</Text>
</Note>
<Image
cache
src='https://picsum.photos/100'
style={{ height: '100px', width: '100px' }}
/>
</Page>
<Page>
<Canvas
debug
paint={drawRectangle}
fixed
bookmark="CanvasTest"
style={{ height: '100vh', width: '100%' }}
></Canvas>
</Page>
</Document>
);
}
ReactPdfHook.js
import { usePDF, Document, Page } from '@react-pdf/renderer';
import { ReactPdfDocument } from './ReactPdf';
const ReactPdfHook = () => {
const [instance, updateInstance] = usePDF({ document: <ReactPdfDocument/> });
if (instance.loading) return <div>Loading ...</div>;
if (instance.error) return <div>Something went wrong: {instance.error}</div>;
return (
<a href={instance.url} download="test.pdf">
Download
</a>
);
}
export default ReactPdfHook;