Saturday, May 11, 2024
 Popular · Latest · Hot · Upcoming
141
rated 0 times [  146] [ 5]  / answers: 1 / hits: 6439  / 4 Years ago, wed, july 8, 2020, 12:00:00

I am using Nest in backend to generate a pdf file with Puppeteer. Puppeteer is working fine when I give it the path to create pdf on disk.


I am currently returning the pdf.


This is the code generating the pdf:


const browser = await puppeteer.launch({ headless: true });
const page = await browser.newPage();
await page.goto('https://blog.risingstack.com', {waitUntil: 'networkidle0'});


var options = {
width: '1230px',
displayHeaderFooter: false,
margin: {
top: "10px",
bottom: "30px"
},
printBackground: true,
}

const pdf = await page.pdf(options);

await browser.close();
return pdf

And this is the controller that calls the previous function:


  @Header('Content-Type', 'application/pdf')
async Printpdf(@Body() message: any) {
console.log(message);
return this.PrintpdfService.printpdf();
}

In React I am calling this with axios like this:


return axios.post(`http://localhost:3000/printpdf`,data, {
responseType: 'arraybuffer',
headers: {
'Accept': 'application/pdf'
}
});

I am trying to download the pdf with this:


getBuildingReport(data).then((response) => {
console.log(response);
const blob = new Blob([response.data], {type: 'application/pdf'})
const link = document.createElement('a')
link.href = window.URL.createObjectURL(blob)
link.download = `name.pdf`
link.click();
})
.catch(err => {
console.log(err)
});

I followed this tutorial.
https://blog.risingstack.com/pdf-from-html-node-js-puppeteer/#option3


But the downloaded pdf is build correctly and is imposible to open it as I get "Failed to load PDF document."


More From » reactjs

 Answers
7

I figured this out for a project once and saved the snippet... The key is loading the PDF into a buffer, and then sending that back to the client.


Here's an example function implemented in a NestJS service:


  async generatePDF(): Promise<Buffer> {
const content = fs.readFileSync(
path.resolve(__dirname, './templates/invoice.html'),
'utf-8'
)

const browser = await puppeteer.launch({ headless: true })
const page = await browser.newPage()
await page.setContent(content)

const buffer = await page.pdf({
format: 'A4',
printBackground: true,
margin: {
left: '0px',
top: '0px',
right: '0px',
bottom: '0px'
}
})

await browser.close()

return buffer
}

Here's an example NestJS controller:


  @Get('/:uuid/pdf')
async getInvoicePdfByUUID(
@Param('uuid', ParseUUIDPipe) uuid: string,
@GetUser() user: User,
@Res() res: Response,
): Promise<void> {

// ...

const buffer = await this.invoicesService.generatePDF()

res.set({
// pdf
'Content-Type': 'application/pdf',
'Content-Disposition': 'attachment; filename=invoice.pdf',
'Content-Length': buffer.length,

// prevent cache
'Cache-Control': 'no-cache, no-store, must-revalidate',
'Pragma': 'no-cache',
'Expires': 0,
})

res.end(buffer)
}

Note that the above assumes you're using NestJS with Express.


Cheers!


[#3246] Monday, July 6, 2020, 4 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
dustin

Total Points: 599
Total Questions: 105
Total Answers: 106

Location: Belarus
Member since Tue, Mar 14, 2023
1 Year ago
dustin questions
Wed, Dec 1, 21, 00:00, 3 Years ago
Wed, Apr 14, 21, 00:00, 3 Years ago
Sun, Sep 20, 20, 00:00, 4 Years ago
;