{"id":2869,"date":"2022-11-05T16:03:30","date_gmt":"2022-11-05T21:03:30","guid":{"rendered":"https:\/\/xlinesoft.com\/blog\/?p=2869"},"modified":"2026-08-16T10:55:41","modified_gmt":"2026-08-16T15:55:41","slug":"generate-pdf-files-using-nodejs-and-pdfmake","status":"publish","type":"post","link":"https:\/\/xlinesoft.com\/blog\/2022\/11\/05\/generate-pdf-files-using-nodejs-and-pdfmake\/","title":{"rendered":"Generate PDF files using NodeJS and PDFMake"},"content":{"rendered":"<p>This tutorial shows how to generate PDF files on the server with Node.js and PDFMake and call the PDF generator from a PHPRunner application. We use the same general approach for documents such as invoices, billing reminders and other PDFs that need to be created automatically on the server.<\/p>\n<h3>Before you start<\/h3>\n<p>You need:<\/p>\n<ul>\n<li>access to the web server where the generated application runs;<\/li>\n<li>permission to install and run Node.js on that server;<\/li>\n<li>a folder in the PHPRunner project where the PDFMake script and its dependencies can be stored;<\/li>\n<li>a writable location for the generated PDF files.<\/li>\n<\/ul>\n<p>The PHP\/PHPRunner part of the application passes the required values to the Node.js script. The Node.js script builds the document definition, generates the PDF and saves it to the location you specify.<\/p>\n<p>1. <a href=\"https:\/\/nodejs.org\/en\/download\/\">Download Node.js<\/a> and install it.<\/p>\n<p>2. Inside your PHPRunner project create a folder named <strong>pdfmake<\/strong>.<\/p>\n<p><a href=\"https:\/\/xlinesoft.com\/blog\/wp-content\/uploads\/2022\/11\/invoice.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/xlinesoft.com\/blog\/wp-content\/uploads\/2022\/11\/invoice-600x406.png\" alt=\"\" width=\"600\" height=\"406\" class=\"alignnone size-medium wp-image-2883\" srcset=\"https:\/\/xlinesoft.com\/blog\/wp-content\/uploads\/2022\/11\/invoice-600x406.png 600w, https:\/\/xlinesoft.com\/blog\/wp-content\/uploads\/2022\/11\/invoice-1024x693.png 1024w, https:\/\/xlinesoft.com\/blog\/wp-content\/uploads\/2022\/11\/invoice-768x520.png 768w, https:\/\/xlinesoft.com\/blog\/wp-content\/uploads\/2022\/11\/invoice-1536x1039.png 1536w, https:\/\/xlinesoft.com\/blog\/wp-content\/uploads\/2022\/11\/invoice.png 1621w\" sizes=\"(max-width: 600px) 100vw, 600px\" \/><\/a><br \/>\n<!--more--><\/p>\n<p>3. Open the command line, navigate to the <strong>pdfmake<\/strong> folder and run:<\/p>\n<div class=\"my-syntax-highlighter\">\n<pre><textarea id=\"mshighlighter\" class=\"mshighlighter\" language=\"\" name=\"mshighlighter\" >\r\nnpm install pdfmake<\/textarea><\/pre>\n<\/div>\n<p>This installs PDFMake and its dependencies. Create a file named <strong>index.js<\/strong> in the <strong>pdfmake<\/strong> folder and use the code below.<\/p>\n<p>4. Here is the code we use to generate the PDF file:<\/p>\n<div class=\"my-syntax-highlighter\">\n<pre><textarea id=\"mshighlighter\" class=\"mshighlighter\" language=\"js\" name=\"mshighlighter\" >\r\nconst PdfPrinter = require('pdfmake');\r\nconst fs = require('fs');\r\n\r\nconst fonts = {\r\n\tRoboto: {\r\n\t\tnormal: 'fonts\/DejaVuSans.ttf',\r\n\t\tbold: 'fonts\/DejaVuSans-Bold.ttf',\r\n\t\titalics: 'fonts\/DejaVuSans.ttf',\r\n\t\tbolditalics: 'fonts\/DejaVuSans-Bold.ttf'\r\n\t}\r\n};\r\n\r\nconst printer = new PdfPrinter(fonts);\r\n\r\nvar params = process.argv;\r\n\r\nvar data = {};\r\ndata.invoicenumber = params[2];\r\ndata.buyeraddress = params[3];\r\ndata.item = params[4];\r\ndata.price = params[5];\r\n\r\nvar docDefinition = {\r\n\tcontent: [\r\n\t\t{\r\n\t\t\tfontSize: 11,\r\n\t\t\ttable: {\r\n\t\t\t\twidths: ['50%', '50%'],\r\n\t\t\t\tbody: [\r\n\t\t\t\t\t[\r\n\t\t\t\t\t\t{\r\n\t\t\t\t\t\t\ttext: 'Status: unpaid',\r\n\t\t\t\t\t\t\tborder: [false, false, false, true],\r\n\t\t\t\t\t\t\tmargin: [-5, 0, 0, 10]\r\n\t\t\t\t\t\t},\r\n\t\t\t\t\t\t{\r\n\t\t\t\t\t\t\ttext: 'Invoice# ' + data.invoicenumber,\r\n\t\t\t\t\t\t\talignment: 'right',\r\n\t\t\t\t\t\t\tborder: [false, false, false, true],\r\n\t\t\t\t\t\t\tmargin: [0, 0, 0, 10]\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t]\r\n\t\t\t\t]\r\n\t\t\t}\r\n\t\t},\r\n\t\t{\r\n\t\t\tlayout: 'noBorders',\r\n\t\t\tfontSize: 11,\r\n\t\t\ttable: {\r\n\t\t\t\twidths: ['100%'],\r\n\t\t\t\tbody: [\r\n\t\t\t\t\t[\r\n\t\t\t\t\t\t{\r\n\t\t\t\t\t\t\ttext: 'Billing address:',\r\n\t\t\t\t\t\t\tmargin: [0, 10, 0, 0]\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t],\r\n\t\t\t\t\t[data.buyeraddress]\r\n\t\t\t\t]\r\n\t\t\t}\r\n\t\t},\r\n\t\t{\r\n\t\t\tfontSize: 11,\r\n\t\t\ttable: {\r\n\t\t\t\twidths: ['5%', '56%', '13%', '13%', '13%'],\r\n\t\t\t\tbody: [\r\n\t\t\t\t\t[\r\n\t\t\t\t\t\t{\r\n\t\t\t\t\t\t\ttext: 'Pos',\r\n\t\t\t\t\t\t\tborder: [false, true, false, true]\r\n\t\t\t\t\t\t},\r\n\t\t\t\t\t\t{\r\n\t\t\t\t\t\t\ttext: 'Item',\r\n\t\t\t\t\t\t\tborder: [false, true, false, true]\r\n\t\t\t\t\t\t},\r\n\t\t\t\t\t\t{\r\n\t\t\t\t\t\t\ttext: 'Price',\r\n\t\t\t\t\t\t\tborder: [false, true, false, true]\r\n\t\t\t\t\t\t},\r\n\t\t\t\t\t\t{\r\n\t\t\t\t\t\t\ttext: 'Quantity',\r\n\t\t\t\t\t\t\talignment: 'center',\r\n\t\t\t\t\t\t\tborder: [false, true, false, true]\r\n\t\t\t\t\t\t},\r\n\t\t\t\t\t\t{\r\n\t\t\t\t\t\t\ttext: 'Total',\r\n\t\t\t\t\t\t\tborder: [false, true, false, true]\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t],\r\n\t\t\t\t\t[\r\n\t\t\t\t\t\t{\r\n\t\t\t\t\t\t\ttext: '1',\r\n\t\t\t\t\t\t\tborder: [false, true, false, true]\r\n\t\t\t\t\t\t},\r\n\t\t\t\t\t\t{\r\n\t\t\t\t\t\t\ttext: data.item,\r\n\t\t\t\t\t\t\tborder: [false, true, false, true]\r\n\t\t\t\t\t\t},\r\n\t\t\t\t\t\t{\r\n\t\t\t\t\t\t\ttext: data.price,\r\n\t\t\t\t\t\t\tborder: [false, true, false, true]\r\n\t\t\t\t\t\t},\r\n\t\t\t\t\t\t{\r\n\t\t\t\t\t\t\ttext: '1',\r\n\t\t\t\t\t\t\talignment: 'center',\r\n\t\t\t\t\t\t\tborder: [false, true, false, true]\r\n\t\t\t\t\t\t},\r\n\t\t\t\t\t\t{\r\n\t\t\t\t\t\t\ttext: data.price,\r\n\t\t\t\t\t\t\tborder: [false, true, false, true]\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t]\r\n\t\t\t\t]\r\n\t\t\t}\r\n\t\t},\r\n\t\t{\r\n\t\t\tfontSize: 11,\r\n\t\t\ttable: {\r\n\t\t\t\twidths: ['88%', '12%'],\r\n\t\t\t\tbody: [\r\n\t\t\t\t\t[\r\n\t\t\t\t\t\t{\r\n\t\t\t\t\t\t\ttext: 'Subtotal:',\r\n\t\t\t\t\t\t\talignment: 'right',\r\n\t\t\t\t\t\t\tmargin: [0, 5, 0, 0]\r\n\t\t\t\t\t\t},\r\n\t\t\t\t\t\t{\r\n\t\t\t\t\t\t\ttext: data.price,\r\n\t\t\t\t\t\t\tmargin: [0, 5, 0, 0]\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t],\r\n\t\t\t\t\t[\r\n\t\t\t\t\t\t{\r\n\t\t\t\t\t\t\ttext: 'Tax %:',\r\n\t\t\t\t\t\t\talignment: 'right'\r\n\t\t\t\t\t\t},\r\n\t\t\t\t\t\t'$0.00'\r\n\t\t\t\t\t]\r\n\t\t\t\t]\r\n\t\t\t}\r\n\t\t},\r\n\t\t{\r\n\t\t\tfontSize: 11,\r\n\t\t\ttable: {\r\n\t\t\t\twidths: ['88%', '12%'],\r\n\t\t\t\tbody: [\r\n\t\t\t\t\t[\r\n\t\t\t\t\t\t{\r\n\t\t\t\t\t\t\ttext: 'Total:',\r\n\t\t\t\t\t\t\talignment: 'right',\r\n\t\t\t\t\t\t\tborder: [false, false, false, true],\r\n\t\t\t\t\t\t\tmargin: [0, 0, 0, 10]\r\n\t\t\t\t\t\t},\r\n\t\t\t\t\t\t{\r\n\t\t\t\t\t\t\ttext: data.price,\r\n\t\t\t\t\t\t\tborder: [false, false, false, true],\r\n\t\t\t\t\t\t\tmargin: [0, 0, 0, 10]\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t]\r\n\t\t\t\t]\r\n\t\t\t}\r\n\t\t},\r\n\t\t{\r\n\t\t\tlayout: 'noBorders',\r\n\t\t\tfontSize: 11,\r\n\t\t\talignment: 'center',\r\n\t\t\ttable: {\r\n\t\t\t\twidths: ['100%'],\r\n\t\t\t\tbody: [\r\n\t\t\t\t\t[\r\n\t\t\t\t\t\t{\r\n\t\t\t\t\t\t\ttext: 'Wire transfer info:',\r\n\t\t\t\t\t\t\tmargin: [0, 10, 0, 0]\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t],\r\n\t\t\t\t\t['SWIFT: ...'],\r\n\t\t\t\t\t['Account number: ...'],\r\n\t\t\t\t\t['Company name: ...'],\r\n\t\t\t\t\t[' '],\r\n\t\t\t\t\t['Company address:'],\r\n\t\t\t\t\t['...']\r\n\t\t\t\t]\r\n\t\t\t}\r\n\t\t}\r\n\t]\r\n};\r\n\r\nvar options = {};\r\n\r\n\/\/ create invoice and save it to invoices_pdf folder\r\nvar pdfDoc = printer.createPdfKitDocument(docDefinition, options);\r\npdfDoc.pipe(fs.createWriteStream('invoices_pdf\/' + data.invoicenumber + '.pdf'));\r\npdfDoc.end();<\/textarea><\/pre>\n<\/div>\n<p>5. Make sure the font files referenced above are available in the <strong>fonts<\/strong> folder and that the <strong>invoices_pdf<\/strong> folder is writable by the account running the web application.<\/p>\n<p>6. Now we are ready to create PDF files. Here is how you execute the script from PHP code:<\/p>\n<div class=\"my-syntax-highlighter\">\n<pre><textarea id=\"mshighlighter\" class=\"mshighlighter\" language=\"php\" name=\"mshighlighter\" >\r\n$param1 = \"62384\";\r\n$param2 = \"1600 Pennsylvania Avenue NW\";\r\n$param3 = \"PHPRunner Enterprise Edition\";\r\n$param4 = \"$999.00\";\r\n\r\nexec(\r\n\t\"\\\"c:\/Program Files\/nodejs\/node.exe\\\" pdfmake\/index.js \" .\r\n\tescapeshellarg($param1) . \" \" .\r\n\tescapeshellarg($param2) . \" \" .\r\n\tescapeshellarg($param3) . \" \" .\r\n\tescapeshellarg($param4)\r\n);<\/textarea><\/pre>\n<\/div>\n<p>Using <strong>escapeshellarg()<\/strong> is important here because values such as addresses and product names may contain spaces.<\/p>\n<p>And the same for C#:<\/p>\n<p>[csharp]<br \/>\ndynamic param1 = &#8220;62384&#8221;;<br \/>\ndynamic param2 = &#8220;1600 Pennsylvania Avenue NW&#8221;;<br \/>\ndynamic param3 = &#8220;PHPRunner Enterprise Edition&#8221;;<br \/>\ndynamic param4 = &#8220;$999.00&#8221;;<\/p>\n<p>CommonFunctions.exec((XVar)(MVCFunctions.Concat(<br \/>\n\t&#8220;\\&#8221;c:\/Program Files\/nodejs\/node.exe\\&#8221; pdfmake\/index.js &#8220;,<br \/>\n\tparam1, &#8221; &#8220;,<br \/>\n\tparam2, &#8221; &#8220;,<br \/>\n\tparam3, &#8221; &#8220;,<br \/>\n\tparam4<br \/>\n)));<br \/>\n[\/csharp]<\/p>\n<h3>Troubleshooting<\/h3>\n<p>If the command works from the command line but not from the web application, check which operating-system account is running the web server and whether that account is allowed to execute Node.js and write to the <strong>invoices_pdf<\/strong> folder.<\/p>\n<p>If PDFMake cannot find a font file, verify the font path relative to the working directory used when the Node.js process starts.<\/p>\n<p>It is also a good idea to test the Node.js command directly on the server with sample parameters before calling it from PHPRunner. That separates Node.js\/PDFMake problems from application-integration problems.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This tutorial shows how to generate PDF files on the server with Node.js and PDFMake and call the PDF generator from a PHPRunner application. We use the same general approach for documents such as invoices, billing reminders and other PDFs that need to be created automatically on the server. Before you start You need: access to the web server where the generated application runs; permission to install and run Node.js on that server; a folder in the PHPRunner project where the PDFMake script and its&#8230;<span class=\"clearfix clearfix-post\"><\/span><a href=\"https:\/\/xlinesoft.com\/blog\/2022\/11\/05\/generate-pdf-files-using-nodejs-and-pdfmake\/\" class=\"more-link\">Continue Reading <span class=\"screen-reader-text\">&#8220;Generate PDF files using NodeJS and PDFMake&#8221;<\/span> <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[16,1,8],"tags":[],"_links":{"self":[{"href":"https:\/\/xlinesoft.com\/blog\/wp-json\/wp\/v2\/posts\/2869"}],"collection":[{"href":"https:\/\/xlinesoft.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/xlinesoft.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/xlinesoft.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/xlinesoft.com\/blog\/wp-json\/wp\/v2\/comments?post=2869"}],"version-history":[{"count":12,"href":"https:\/\/xlinesoft.com\/blog\/wp-json\/wp\/v2\/posts\/2869\/revisions"}],"predecessor-version":[{"id":3432,"href":"https:\/\/xlinesoft.com\/blog\/wp-json\/wp\/v2\/posts\/2869\/revisions\/3432"}],"wp:attachment":[{"href":"https:\/\/xlinesoft.com\/blog\/wp-json\/wp\/v2\/media?parent=2869"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/xlinesoft.com\/blog\/wp-json\/wp\/v2\/categories?post=2869"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/xlinesoft.com\/blog\/wp-json\/wp\/v2\/tags?post=2869"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}