I am trying to generate PDF of a page which is heavily loaded with images in react app. So far I was able to generate it on frontend i.e., in react. But it takes too much time to generate and download. As the images are very high resolution the browser takes a toll in loading them and also crashes due to insufficient memory. So after discussion I tried to execute this process in backend (node server).
I implemented puppeteer . I am sending the HTML code of the pdf page from react to node and trying to generate the pdf.
Everything goes well, only the images which I have rendered in canvas in original react page are not displayed in the generated PDF. The images which are displayed normally are getting loaded properly in generated PDF, only those which are rendered through canvas or also a graph in canvas is not loading in PDF.
Here's my code - (Currently I am using a sample html file which have the html code from react)
`
async function getTemplateHtml() {
console.log("Loading template file in memory")
try {
const invoicePath = path.resolve(`${__dirname}/invoice.html`); //temporary html template file
return await readFile(invoicePath, 'utf8');
} catch (err) {
console.log(err);
return Promise.reject("Could not load html template");
}
}
exports.generatePdf = async (req, res) => {
getTemplateHtml().then(async (tmpres) => {
const browser = await puppeteer.launch();
const page = await browser.newPage()
.catch((err) => {
console.log('page: ', err);
});
await page.setContent(tmpres)
await page.setViewport({
width: 1280,
height: 1024,
deviceScaleFactor: 1,
});
await page.evaluate(async () => {
let scrollPosition = 0;
let documentHeight = document.body.scrollHeight;
while (documentHeight > scrollPosition) {
window.scrollBy(0, documentHeight);
await new Promise((resolve) => {
setTimeout(resolve, 100);
});
scrollPosition = documentHeight;
documentHeight = document.body.scrollHeight;
}
});
const buffer = await page.pdf({
path: `${__dirname}/invoice.pdf`,
format: 'a4',
margin: {
top: '1cm',
bottom: '1.5cm',
},
})
.catch((err) => {
// eslint-disable-next-line no-console
console.log('page.pdf: ', err);
});
await browser.close()
.catch((err) => {
console.log('close: ', err);
});
const base64 = buffer.toString('base64');
fs.writeFileSync(`${__dirname}/temp.txt`, base64)
})
.catch(error => {
console.log(error)
})
})
Here is the page I want to print to PDF :
Also here is the resultant PDF :