Adapting jsreport

Configuration file

The most common way to adapt jsreport settings is using configuration file. Configuration file is stored at the root directory with name jsreport.config.json. Editing this file you can change for example port service is running on or scale up number of worker processes jsreport uses. You can find full documentation of various options here.

Configuring using nodejs

In addition to configuration file based settings you can also use node.js and dynamically adapt jsreport to your needs. Following chapters applies to those using jsreport on premise and want to apply some advanced configurations.

Installing and initializing jsreport on premise will create server.js file containing the following code:

require('jsreport')().init();

This is the most basic jsreport server startup. It searches for jsreport.config.json file and initialize server based on the settings it finds in it or applies defaults. Same code can be also used when integrating jsreport directly to the existing nodejs application.

In addition to configuration file, jsreport also parses values from environment variables, command line arguments or you can pass them directly to the jsreport instantiation. Options passed as a parameter take precedence over environment variables which then take precedence over configuration file.

In the following example are the options passed directly to the jsreport instantiation.

require('jsreport')({ httpPort: 3000, httpsPort: 0 }).init();

Additional extensions

jsreport can be easily extended with additional extensions. Extension usually adds a new engine, recipe or even complex studio functionality. There are plenty of them ready to be installed like extension allowing you to store templates in mongodb or another extension storing reports in Microsoft Azure. You can find the list of extensions in the jsreport official documentation or on the github. If you didn't find what you are looking for, you can even implement your own custom extension. This topic is described separately here.

Rendering

The goal of jsreport is to render reports. To do it programmatically you use jsreport.render:

jsreport.init().then(() => {
  jsreport.render({
    template: {
      content: '<h1>Hello {{foo}}</h1>',
      engine: 'handlebars',
      recipe: 'chrome-pdf'
    },
    data: {
      foo: "world"
    }
  }).then((resp) => {
    // write report buffer to a file
    fs.writeFileSync('report.pdf', resp.content)    
  });
}).catch((e) => {
  console.log(e)
});

See the jsreport-core for complete documentation for rendering.

Debugging

In order to debug your jsreport app with nodejs debugging tools you will need to change your configuration for templatingEngines.strategy to in-process, this ensures that all operations in the rendering pipeline of jsreport are executed in the same process, which is something handy when debugging because there will be just single process needed to inspect.

Attach to existing express app

jsreport by default starts express.js based server running on ports specified in config. This behavior can be overridden with passing express application instance to the options. In this case jsreport express extension will just add required routes and middle-wares to the passed instance.

const express = require('express');
const app = express();

app.get('/', (req, res) => {
  res.send('Hello from the main application');
});

const reportingApp = express();
app.use('/reporting', reportingApp);

const server = app.listen(3000);

const jsreport = require('jsreport')({
  extensions: {
      express: { app: reportingApp, server: server },
  },
  appPath: "/reporting"
});

jsreport.init().then(() => {
  console.log('jsreport server started')
}).catch((e) => {
  console.error(e);
});

Using rendering shortcut

It can be convenient sometimes to use jsreport shortcut require("jsreport").render if you want just to render a report. This happens to be usefull when you are not interested in starting jsreport server or storing data in the document store. Shortcut doesn't use configuration files but instead you can add/modify configurations dynamicaly into require("jsreport").renderDefaults, just make sure to only modify the existing require("jsreport").renderDefaults object, if you assign a new object in renderDefaults it will not be recognized.

const http = require('http');
const jsreport = require('jsreport');

http.createServer((req, res) => {
  jsreport.render({
    template: {
      content: 'Hello world',
      engine: 'handlebars',
      recipe: 'chrome-pdf'
    }
  }).then((out) => {
    out.stream.pipe(res);
  }).catch((e) => {
    res.end(e.message);
  });
}).listen(1337, '127.0.0.1');

Dynamic access to jsreport entities

Once you have the jsreport running with some templates or reports created. You can reach them on the server using documentStore property. The API to search and manipulate underlying jsreport data is very similar to official mongodb driver. It is just using promises.

reporter.documentStore
.collection('templates')
.find({ name: 'test'})
.then(function(res) {
  // use the entity results for your own purpose
    console.log(res)
});

You can read more about documentStore in the article describing how to write custom extension.