NodeJS : How to generate and properly serve PDF
When it comes to client side PDF generation, there are loads of guides out there especially when compared to the same implementation on server side & even lesser guides on how to serve that generated PDF data properly to the client(or store it in the server if need be). In this guide I will be concentrating on exactly those using NodeJS environment, namely:
- Generate a PDF and respond to client(base64 string) and how to use that string in the client-side to display the PDF.
- Generate a PDF and respond to client for auto download.
- Generate a PDF and store it in the server.
For this guide, I’m going to make use of the pdfmake
npm package which is one of the best in business for PDF creation. The package can be installed by running the following command
npm install pdfmake --save
I will refrain from diving deep into the details of the package methods(which you can read from here), instead I will concentrate more on implementing the package to generate a PDF and more importantly how to handle that PDF data.
Generate a PDF and respond to client(base64 string)
Let’s consider a simple example to create PDF using pdfmake
and responding with base64 string is:
docDefinition
in the above snippet is simply an object that is fed into the createPdfKitDocument method. It holds the main content(including their format and styling) of the PDF. A very detailed explanation on how you can add & format the content can be found on their github page.
The .on(‘data’
event pumps the data into an array which is later concatenated into a Buffer object which is then used for the response depending on various scenarios.
In this scenario, the line to be highlighted is
callback('data:application/pdf;base64,'+result.toString('base64'));
The Buffer object created is converted to a base64 encoded string prefixed with data:application/pdf;base64,
and then sent to the client. The response string would look something like
data:application/pdf;base64,JVBERi0xLjcKCjEgMCBvYmogICUgZW50cnkgcG9pbnQKPDwKICAvVHlwZSAvQ2F0YWxvZwogIC9Q...
This string can then be used on client-side as the value to a href
attribute of an anchor element like so.
<a href=”data:application/pdf;base64,JVBERi0xLjc…”>
Open PDF
</a>
Note: Try opening in a new window if the click on link doesn’t work.
Generate a PDF and respond to client for auto download
Almost the entire implementation remains the same as base64, except at the time of sending the response(within the .on(‘end’
). For auto download, instead of converting to base64 encoded string we just need to send the concatenated Buffer object as the response to the client.
Buffer.concat(chunks); // <Buffer 88 13 a0 0f ...>
Additionally before sending the response, we need to set the header Content-Type
to application/pdf
.
The code would look like(rest of the generatePdf
function would remain the same as the above base64 example) :
Note: While saving the file, add the .pdf extension.
Generate a PDF and store it in the server
For Storing the created PDF in server, instead of creating an array and pumping the data into it we just have to pipe the data into a writable stream using the NodeJS fs
(file system) module. createWriteStream
takes in a path parameter which signifies the destination of the file to be saved.
Let’s also add some basic error handling to capture streaming error(s) such as incorrect destination folder passed etc.
The above would create a “filename.pdf” within the “docs” folder found at the root of the project.
Hope this guide helps most coders, if not all, struggling to implement PDF generation and more importantly how to handle the generated data.