Generate PDF files using NodeJS and PDFMake
Tags: webdev, node, pdf
Published: 2022-11-08 23:43:51

In this article we will show you how to generate PDF invoices on the web server side. At [Xlinesoft](https://xlinesoft.com/), we use this approach to generate and email billing reminders to our customers.

1. [Download](https://nodejs.org/en/download/) NodeJS to your web server. For Windows choose 64-bit MSI installer.

2. Run and install keeping all default settings. 

3. Inside your project create a new folder named **pdfmake**. 

4. Proceed to that folder, start the command line and run: 

```
npm install pdfmake
```

5. This will create index.js, in this file we will add the code that create PDF file. In our case, we will be generating due invoices for our customers.

[PDFMake documentation](https://pdfmake.github.io/docs/0.1/getting-started/server-side/)

Here is the **index.js** file we that generates invoices.

```
var fonts = {
   Roboto: {
     normal: 'jsnode/fonts/DejaVuSans.ttf',
     bold: 'jsnode/fonts/DejaVuSans-Bold.ttf',
     italics: 'jsnode/fonts/DejaVuSans.ttf',
     bolditalics: 'jsnode/fonts/DejaVuSans.ttf'
   }
}

var PdfPrinter = require('pdfmake');
var printer = new PdfPrinter(fonts);
var fs = require('fs');

// reading parameters from the command line
var params = process.argv;
var data = [];
data["invoicenumber"] = params[2];
data["buyeraddress"] = params[3]
data["item"] = params[4];
data["price"] = params[5];

// json with invoice layout 
var docDefinition = {
	content: [
		{
			fontSize: 11,
			table:{
				widths: ['50%','50%'],
				body:[
					[{text:'Status: unpaid', border:[false,false,false,true],margin:[-5,0,0,10]},{text:'Invoice# '+data.invoicenumber, alignment:'right', border:[false,false,false,true],margin:[0,0,0,10]}]
				]
			}
		},
		{
			layout: 'noBorders',
			fontSize: 11,
			table:{
				widths: ['50%','50%'],
				body:[
					[{text:'Website.com',margin:[0,10,0,0]},{text:'Invoice date: '+data.invoicedata, alignment:'right',margin:[0,10,0,0]}],
					['...',''],
					['...',''],
					['...','']
				]
			}
		},
		{
			fontSize: 11,
			table:{
				widths: ['50%','50%'],
				body:[
					[{text:' ', border:[false,false,false,true],margin:[0,0,0,10]},{text:'Payment amount: $'+data.price, alignment:'right', border:[false,false,false,true],margin:[0,0,0,10]}]
				]
			}
		},
		{
			layout: 'noBorders',
			fontSize: 11,
			table:{
				widths: ['100%'],
				body:[
					[{text:'User account for payment:',margin:[0,10,0,0]}],
					[data.buyerinfo],
					[data.buyeraddress],
					['Payment link:'],
					[{text:'https://website.com/shopcart/invoices_view.php?hash='+data.hash,margin:[0,0,0,10],fontSize:10}]
				]
			}
		},
		{
			fontSize: 11,
			table:{
				widths: ['5%','56%','13%','13%','13%'],
				body:[
					[{text:'Pos', border:[false,true,false,true]},{text:'Item', border:[false,true,false,true]},{text:'Price', border:[false,true,false,true]},{text:'Quantity',alignment:'center', border:[false,true,false,true]},{text:'Total', border:[false,true,false,true]}],
					[{text:'1', border:[false,true,false,true]},{text:data.item, border:[false,true,false,true]},{text:"$"+data.price, border:[false,true,false,true]},{text:'1',alignment:'center', border:[false,true,false,true]},{text:"$"+data.price, border:[false,true,false,true]}]
				]
			}
		},
		{
			layout: 'noBorders',
			fontSize: 11,
			margin:[0,0,5,0],
			table:{
				widths: ['88%','12%'],
				body:[
					[{text:'Subtotal:', alignment:'right',margin:[0,5,0,0]},{text:'$'+data.price,margin:[0,5,0,0]}],
					[{text:'Tax %:', alignment:'right'},'$0.00'],

				]
			}
		},
		{
			fontSize: 11,
			table:{
				widths: ['88%','12%'],
				body:[
					[{text:'Total:', alignment:'right', border:[false,false,false,true],margin:[0,0,0,10]},{text:'$'+data.price, border:[false,false,false,true],margin:[0,0,0,10]}]
				]
			}
		},
		{
			layout: 'noBorders',
			fontSize: 11,
			alignment: 'center',
			table:{
				widths: ['100%'],
				body:[
					[{text:'Wire transfer info:',margin:[0,10,0,0]}],
					['SWIFT: ...'],
					['Account number: ...'],
					['Company name: ...'],
					[' '],
					['Company address:'],
					['...']
				]
			}
		}
	]

};
var options = {};

// create invoice and save it to invoices_pdf folder 
var pdfDoc = printer.createPdfKitDocument(docDefinition, options);
pdfDoc.pipe(fs.createWriteStream('invoices_pdf/'+data.invoicenumber+'.pdf'));
pdfDoc.end();
```

6. Now we are ready to create PDF files. In our case we run a cron once a day that is a PHP file that creates and emails invoices. Here is a sample PHP code:

```
$param1 = "62384";
$param2 = "1600 Pennsylvania Avenue NW";
$param3 = "PHPRunner Enterprise Edition";
$param4 = "$999.00";
exec("\"c:/Program Files/nodejs/node.exe\" pdfmake/index.js ".$param1." ".$param2. " ". $param3." ".$param4);
```