How to generate PDF of a website page with Node.js
Easily create the same quality of pdf that we get when we do Ctrl + P or Command + P (Mac) on Chrome Browser to print the pdf
In this article, we will see how easy it is to generate PDF of any webpage using Nodejs and send the generated pdf back to the client side application.
We will use puppeteer tool which is a headless chrome API to generate pdf
So let’s get started.
Create a package.json file using
npm init -y
Install puppeteer using
npm install --save puppeteer@2.0.0
We will generate a sample pdf of the hacker news page.
Create a server folder and add index.js
file inside it with the following code:
The waitUntil
option in the above code will wait for the page to load completely before generating a pdf.
To execute the code, run
node server/index.js
Once you execute the above command, you will see a new pdf file with the name hacker_news.pdf
is generated.
If you want to maintain the background color of the webpage, you need to add printBackground: true
option while generating pdf
We have used the A4
format for creating pdf.
The most widely used formats are A4
and Letter
.
Otherformat
options are:
Letter
: 8.5in x 11inLegal
: 8.5in x 14inTabloid
: 11in x 17inLedger
: 17in x 11inA0
: 33.1in x 46.8inA1
: 23.4in x 33.1inA2
: 16.54in x 23.4inA3
: 11.7in x 16.54inA4
: 8.27in x 11.7inA5
: 5.83in x 8.27inA6
: 4.13in x 5.83in
You can set viewport width and height using setViewport
before generating pdf using page.pdf
function
await page.setViewport({ width: 1680, height: 1050 });
If you want to display the default header and footer, you need to add displayHeaderFooter
option and specify the margin for header and footer
This will add the header with the current date in pdf as shown below
and page URL will be added in the footer in pdf as shown below
We have provided a 38px margin for all the sides for the header and footer which is approximately equal to 1cm.
Custom header and footer:
We can also provide our custom header and footer using headerTemplate
and footerTemplate
options respectively.
In all of the above examples, we are storing the generated pdf in the root folder which is not ideal.
Let’s see how we can change the location to store the generated pdf files.
We will use the current timestamp to use as the name for the generated pdf.
Create a new files
folder in server
directory.
Import the path node package at the top:
const path = require('path');
Get today’s date using:
const todays_date = new Date();
change path option in page.pdf function to
path: `${path.join(__dirname, 'files', todays_date.getTime() + '.pdf')}`,
__dirname
points to the current directory which is server
in our case.
We are using the join method of the path node package so it will correctly create the file because Linux/mac path has forward slashes in the file path and windows has backward slashes.
The path
node package handles this conversion for us automatically.
Now we will connect our backend nodejs with the front end so we can send the pdf from server to client when the user clicks on a button or a link to download the pdf
Install express using:
npm install --save express@4.17.1
Create a new file server.js
and add the express app using
const express = require('express');
const app = express();
1.Copy the previous code of pdf generation in the get handler and start the server using app.listen
2. Store the pdf file path in a separate variable so we can use it later
const pdfURL = path.join(__dirname, 'files', todays_date.getTime() + '.pdf');
3. Store the result from page.pdf
function call in pdf variable
4. Set the response content type and send the pdf back to the client using
res.set({
"Content-Type": "application/pdf",
"Content-Length": pdf.length
});res.sendFile(pdfURL);
If you are having trouble understanding the server creation code, check out my previous article regarding creating REST API’s in Nodejs HERE.
Now start the express server by executing
node server/server.js
and navigate to http://localhost:5000/pdf
You will see your generated pdf in the browser
Now, create a public folder and index.html inside it with the following content
In server/server.js
file, before the get /pdf
route, specify the public
folder path so we can access all the files under the public folder
app.use(express.static(path.join(__dirname, '..', 'public')));
Now, restart the server using
node server/server.js
and navigate to http://localhost:5000/ which will load the index.html
file we created
If you click the GET PDF link, you will be able to see the generated pdf where you can view or download the pdf file
We can also add any CSS styling to the generated pdf using
await page.addStyleTag({
content: `
body { border: 1px solid #ccc }
`
});
We will need to call the addStyleTag before calling the page.pdf method.
Generate PDF from local HTML file:
To generate a pdf from an HTML file we need to specify the HTML file url using file:<path_of_file> inside the page.goto
method
Create a lorem.html
file inside the public
directory with the following content
and reference the file in page.goto
function as
await page.goto(`file:${path.join(__dirname, '..' , 'public', 'lorem.html')}`, { waitUntil: "networkidle2" });
To learn more about puppeteer check HERE
Puppeteer Documentation: https://pptr.dev/
Complete Github Source Code: https://github.com/myogeshchavan97/pdf_generation_puppeteer
That’s it for today. Hope you learned something new today.
Don’t forget to subscribe to get my weekly newsletter with amazing tips, tricks, and articles directly in your inbox here.