DEV Community

Cover image for Generate PDF files using NodeJS and PDFMake
Sergey Kornilov
Sergey Kornilov

Posted on

Generate PDF files using NodeJS and PDFMake

In this article we will show you how to generate PDF invoices on the web server side. At Xlinesoft, we use this approach to generate and email billing reminders to our customers.

  1. 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
Enter fullscreen mode Exit fullscreen mode
  1. 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

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();
Enter fullscreen mode Exit fullscreen mode
  1. 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);
Enter fullscreen mode Exit fullscreen mode

Top comments (1)

Collapse
 
bossysmaxx profile image
BossySmaxx • Edited

good tutorial more worth than 1000 youtube videos, I think I gotta start reading articles again. Got bad habits of searching for everything on youtube, Wasted hours for this solution