Just released: jsreports 1.4.87

Quick update: we just released version 1.4.87 of jsreports! You’ll notice some visual updates to the designer’s look and feel, plus a bunch of other improvements throughout the product.

If you’re looking for the new element menu, it’s been moved into a menu button in the left margin of the template, leaving more room for the template itself.

We’re also expanding what you can do with data sources, allowing you to define data sources that depend on (and transform) other data sources.

Expect more updates to the designer in the coming months.

Version 1.4.75 released

Here are some of the new features available today in version 1.4.75.  Download the free trial here: https://jsreports.com/trial.

  • New features for table rendering in PDF: background images, cell padding
  • Improved handling of large text blocks including Markdown bullet lists and page breaking in PDF
  • Improved support for nested JSON data structures via dot syntax (“row.field1.field2”) and autocomplete
  • Default element properties
  • New Line element
  • Multiple data sources and multiple detail sections per data row
  • And more!  See the release notes here: https://jsreports.com/docs/changelog

 

ES6 classes are pretty handy for extensibility

ES6 introduced syntax sugar for something a lot of people were already doing in ES5, namely simulating classical object-oriented inheritance.  That move got some blowback from people who say that prototypal inheritance is better, or classes are terrible.  And it’s true that classes aren’t really a natural part of JavaScript.

We had a scenario recently though where we found that ES6 classes were a good fit.  We were adding the ability to define your own custom elements in jsreports.  These are basically custom components that leverage built-in behavior and add their own logic too.  For example, you can define a checkbox component with a boolean “checked” property that toggles based on a data calculation (this is actually one of the examples we provide, because it’s so simple).

Here are some of the advantages we found when using classes:

  • The ES6 class syntax is concise and easy to read; it’s easy to take a class we provide and pretty easily see where the natural extension points are.  The class structure is a good way for our code to self-document what it is and how it relates to other components.
  • Classes are a good match when the thing you’re modeling already has an “is-a” relationship.  In our case, custom elements are natural subclasses of an abstract Element type that already has many concrete implementations.
  • Having a built-in class syntax allows you to “say what you mean” in the code, instead of piecing together a bunch of functions and prototypes manually.  On top of the human readability advantage already mentioned, this opens the door to better documentation generation and tooling.

But there are some things to watch out for, too:

  • The explosion of subclasses.  In a way, classes provide the perfect trap for programmers who are already tempted to over-abstract things.  The antidote (for us) is to keep class hierarchies shallow and class count low, and tend toward composition where possible.
  • Since this is just sugar, it’s important to have a good understanding of how concepts like statics and visibility work in the underlying JavaScript.  If your experience with classes comes from a language like Java or C#, there are some surprises in store.
  • ES6 doesn’t support interfaces, which would be helpful in our scenario.

Now, not all of our customers are using an ES6 environment yet.  We still provide our pre-built bundles in ES5, but we also ship (to customers) our Babel build chain and ES6 source.

We’re pretty happy with how well it’s worked out so far.

For more on ES6 classes, see https://hacks.mozilla.org/2015/07/es6-in-depth-classes/.

Useful thoughts on API design and classes can be found in Joshua Bloch’s classic presentation “How to Design a Good API and Why It Matters.”

Announcing jsreports + Sencha ExtJS integration

Do you use Sencha’s ExtJS framework and need to generate printable reports from your data? We just released a jsreports integration with ExtJS that you should check out.

Screen Shot 2016-08-09 at 12.03.57 AM

We provide two new ExtJS components, Viewer and Designer, that encapsulate those two jsreports modes. That makes it super easy to drop them into an existing ExtJS app.

What’s more, you can use your existing ExtJS data stores as data sources for the reports. So your existing data models provide the schema and you don’t need to do anything else. Let ExtJS handle the data fetching for you.

A demo with source code is here:
https://jsreports.com/examples/extjs/

Documentation is here:
https://jsreports.com/docs/extjs/#!/api/jsreports.integrations.extjs.Designer

Get in touch via email at support@jsreports.com to let us know what we should add next!

Version 1.4.40 released with new designer features

We just released version 1.4.40 with a slate of updates across the product. Some important changes are in the designer, including:

– Fonts are now scaled in the template to better represent their size in the final output
– You can hide the left settings pane using config option showSettingsPane: false
– You can define your own pre-configured elements and put them in the toolbar for use in reports

On that last one, we’ll have a demo out next week that shows how to implement your own custom controls. We’re just getting started in this area and have big plans for this feature.

See the whole list of changes at the changelog .

Demo: Rendering reports on the server with Node.js and jsreports

Here’s a quick example of how to run reports on the server using Node.js.  The way it works is simple:

  1. Import the jsreports-server module from the jsreports distribution,
  2. Load your report definition and data source JSON files just like you would in the browser, and
  3. Call server.export() on a new Server instance.

Important: before running your script, you’ll need to install the phantomjs-prebuilt package:

npm install -g phantomjs-prebuilt

Here’s some sample code showing how easy it is:

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

// Import the jsreports server package
var jsreports = require('./lib/jsreports/jsreports-server.js');

var server = new jsreports.Server();

// Load the report from a .json file on disk
var report = require('./reports/report.json');

// For demo purposes only; returns an array of data source configurations, just as in the browser
var datasets = require('./datasets.js');

// Call server.export() just like you would call jsreports.export() in the browser
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, use the current directory
   imageUrlPrefix: 'file://' + path.resolve(__dirname) + '/'
}, function(err, pdfStream) {
  if (err) return console.error(err);
  // Got the output stream - write PDF to file
  var outPath = path.resolve(__dirname, 'out-' + (new Date()).getTime() + '.pdf');
  var outStream = fs.createWriteStream(outPath, 'utf8');
  pdfStream.on('end', function() { 
    console.log('Wrote PDF to', outPath);
    server.stop();
  });
  pdfStream.pipe(outStream);
});

Call server.stop() when you’re done rendering.  If you don’t, the Server instance will remain running to serve future requests.  By default, up to 3 worker processes will handle reports in parallel as needed.

As always, get in touch with us at support@jsreports.com if you have any questions!

jsreports version 1.4.27 released with a focus on performance for massive reports

We just released version 1.4.27 of jsreports, and it includes big improvements to report rendering performance. HTML rendering of reports with millions of elements is up to 200% faster, and reports with many nested subreports are up to 500% faster. PDF export is 300-500% faster. Good stuff! We will continuing to add to these performance improvements over time.

If you have a report with hundreds of thousands of sections being rendered in HTML, you can improve scrolling performance by setting enableVirtualRender: true as a config option when calling jsreports.render().

Lots more to come on the features front, but it’ll have to wait for a future blog post.

Expanding support for Jasper Reports

We’ve just released jsreports version 1.4.11 with support for additional Jasper Reports features (hurray, barcodes!).  If you’re already using Jasper Reports in your application, you can use jsreports in a couple of ways:

  1. Edit existing Jasper Reports in the web browser using the jsreports designer
  2. Create brand new Jasper Reports in the browser

Here’s an actual Jasper report being edited in the jsreports HTML5 report designer component:

jasper-report-in-jsreports-designer

Providing the ability to modify Jasper reports in the browser gives your customers a seamless experience – no need to deal with a separate desktop application and its dependencies and no files to transfer around.  In addition, the jsreports designer is made to be simple and intuitive, providing the most-needed features front and center so non-experts can be productive with it.

Here’s more detail on how to achieve the two use cases mentioned above.

1. Editing existing Jasper Reports in the web browser using the jsreports designer

First, get jsreports included in your webpage following the instructions at http://jsreports.com/docs/getting-started/#installation.

Now, you’ll need to get the existing report’s .jrxml to the browser somehow.  How you do it will depend on your tech stack.  For now, we’ll imagine you have some static reports stored under the /reports path on your server, and we’ll just use jQuery to pull in the file.

$.get("/reports/my-report.jrxml", function(jrxml) { 
    //...

Once the file is available at the client, you only need a line of code that calls the fromJRXML method on the jsreports.integrations.jasper.JasperReportDef class, which we’ve aliased here for brevity.

var JasperReportDef = jsreports.integrations.jasper.JasperReportDef; 
var reportDef = JasperReportDef.fromJRXML(jrxml);

That gives you a report definition object you can pass to the designer.  Here it is all together:

// Alias JasperReportDef for brevity 
var JasperReportDef = jsreports.integrations.jasper.JasperReportDef; 
// Fetch .jrxml file
$.get("/reports/my-report.jrxml", function(jrxml) {
    // Convert to jsreports format
    var reportDef = JasperReportDef.fromJRXML(jrxml);
    // Create designer and pass it the report definition
    var designer = new jsreports.Designer({
        data_sources: [], // Will use the embedded data source information
        report: reportDef
    });
});

2. Creating brand new Jasper Reports in the browser

As before, make sure you’ve got the jsreports designer included on your page.  This time, instead of pulling in a .jrxml file, we’ll just create a blank report.

// Alias JasperReportDef for brevity 
var JasperReportDef = jsreports.integrations.jasper.JasperReportDef;
// Create a new, blank Jasper report
var reportDef = new JasperReportDef();

The rest of the code is the same – instantiate a Designer and pass this reportDef to it, then when the designer is saved, you’ll get the resulting .jrxml as before and can save the new report to the server for rendering with Jasper.

It’s that easy!  If you have questions, get in touch with support@jsreports.com.

For more details, see our documentation on using the jsreports report designer with Jasper Reports.

What we’re up to

OK, I’ve been getting more and more questions about our roadmap so I thought I’d provide a little color on that here.  While we don’t yet publicly lay out our roadmap in detail, I can give an outline.

Over the next quarter or so we’ve got lots of improvements to the core reporting engine underway.  Some of these are what you’d call nice-to-haves, like font embedding in PDFs.  Some are critical enablers, like internationalization, custom elements, and event hooks.

In parallel with that, we have our first release of server-side rendering (for Node.js) coming up soon which I think is really cool.  We’ll be using that technology to provide a cloud reporting API for developers.

Along with all this we’re working to keep improving the documentation and resources we provide to customers.  We’re also working hard with our OEM customers to make it as easy as possible to embed jsreports, since the demand for that use case has been significant.

So, lots coming in the next few months!  Contact me at emil@jsreports.com for more detail on any of this.

The new documentation is here!

We’ve been working hard to improve our documentation and our whole documentation-generating system along with it, because we have a lot of new features upcoming and it’s important that we be able to keep the docs up to date as jsreports evolves.

The early results are starting to arrive, and I’m happy to announce a whole new look for the documentation site.  For developers, there are new resources like a reference for our JSON report definition format, and docs for the report builder API.  For end users (people designing reports using the report designer), we’ve got a section just for you that explains how to design reports.

We’re using a new toolchain with some cool open-source pieces to make this documentation system possible, and I’ll probably get around to writing about it one of these days.  In the meantime, check it out and email us at support@jsreports.com with any questions or suggestions.