Generating PDF reports on the server using Node.js and jsreports

This tutorial shows how to run jsreports within Node.js to generate PDF documents on the server. This can be very useful, for example, when you want to generate and send reports via email on a schedule.

The process is almost identical to generating the PDF client-side. You just need to import the jsreports Server module for Node.js and then call jsreports.export with your report template and data sources.

Requirements

First, install a pre-packaged version of PhantomJS for your platform by running the following command at a command line:

npm install -g phantomjs-prebuilt

(Note: if you have trouble with SSL during the installation due to a network firewall, read How to temporarily skip SSL validation with npm. You can revert this setting after the installation.)

Setting up the script

Create a file named run-report.js with the following code:

var fs = require('fs');
var path = require('path');

/** Import the jsreports server module and create a Server instance */
var jsreports = require('./lib/jsreports/jsreports-server.js');
var server = new jsreports.Server();

/**
 * Load the report and data source definitions from
 * JSON files specified in command line arguments.
 */
var report = require(process.argv[2]);
var datasets = require(process.argv[3]);

/**
 * Call server.export() just like you would call jsreports.export().
 * The last argument is a callback function that will be called with
 * a stream containing the PDF for reading.
 */
server.export({
   format: 'PDF',
   report_def: report,
   datasets: datasets,
   /**
    * Must provide a file:// base URL to prepend to the image 
    * URLs in the report, in order to locate them on the server - 
    * here, expect images to be in the current directory
    */
   imageUrlPrefix: 'file://' + path.resolve(__dirname) + '/'
}, function(err, pdfStream) {
  if (err) return console.error(err);
  /**
   * At this point we have the PDF available for reading
   * in pdfStream.  Write it to the path specified at 
   * the command line
   */
  var outPath = path.resolve(process.argv[4]);
  var outStream = fs.createWriteStream(outPath, 'utf8');
  pdfStream.on('end', function() {
    console.log('Wrote PDF to', outPath);
    server.stop();
  });
  pdfStream.pipe(outStream);
});

Running the report from the command line

On the server, at a command line run the following:

node run-report.js