DEV Community

Cover image for Creating dynamic reports with CarboneJS V2
Steeve for Carbone

Posted on • Edited on

Creating dynamic reports with CarboneJS V2

The Carbone team has released a major update to add the possibility to create complex reports easily. In the v2.0.0, the core has been rewritten to fix a security breach, reduce memory consumption, and gain stability! In this article, we will go through the new and cool features:

  • Dynamic variables in all formatters
  • Dynamic content πŸŽ‰
  • Beta Rendering dynamic charts

Everything mentioned in this article is available on the Carbone Changelog.

What is Carbone? It is a report generator using a JSON dataset and an XML based template (ODT/DOCX/XLSX/ODS/...). I have already made an introduction about it, check this out!

If you want to learn more about Carbone, check out the project on Github: https://github.com/Ideolys/carbone

Dynamic variables in all formatters

For the next examples, the following JSON dataset is going to be used:

{
  "quantity": 3
  "numberSupply": {
    "nbrA": 10,
    "nbrB": 5
  },
  "references": {
    "id1": "Invoice 123",
    "id2": "Bill 402"
  }
}
Enter fullscreen mode Exit fullscreen mode

It is possible to pass variables to formatter arguments, here is an addition on a DOCX template:
carbone addition

Carbone translates the marker {d.numberSupply.nbrA:add(.nbrB)} to 10 + 5 and it prints the result 15 on the report.

Adding dots can be used to backtrack to the parent object. Let's multiply by the quantity:

Multiply on reports

The marker {d.numberSupply.nbrA:add(.nbrB):mul(..quantity)} is translated to (10 + 5) * 3and it prints: 45

There's no limit in depth to access to a parent object with dots. If an element doesn't exist, the error [[C_ERROR]] badAttr not defined is returned. In the end, it is not possible to pass an array to a formatter argument.

Dynamic content block and conditional formatters

The main feature of the V2 update is the conditional sections, in other words, selectively show content on the report. Here is a template example:

Alt Text

  1. Markers {d.isHidden:hideBegin()} and {d.isHidden:hideEnd()} surrounding the content define the beginning and the end of the section to hide.
  2. If the value of the data isHidden is true, the table is going to be hidden, otherwise, it appears on the report.

The result:
conditional_content

The same result can be done with the pair :showBegin()/:showEnd().

Finally, a new set of conditional formatter came out:

  • :ifEQ(value) Matches values that are equal to a specified value. The opposite is :ifNEQ().
  • :ifGT(value) Matches values that are greater than a specified value. You can check the equality with :ifGTE().
  • :ifLT(value) Matches values that are less than a specified value. You can check the equality with :ifLTE().
  • :ifIN(value) Matches any of the values specified in an array or string. The opposite is :ifNIN().
  • :ifEM(value) Matches empty values, string, arrays or objects. The opposite is :ifNEM().
  • :and(value) AND operator between two consecutive conditional formatters.
  • :or(value) OR operator between two consecutive conditional formatters.

It helps a lot to add logic in the report, such as showing a specific title in a DOCX report:

Title DOCX

This is the equivalent in javascript:

if (d.quantity > 2 || d.numberSupply.nbrA == 8) {
  print(d.references.id1)
}
Enter fullscreen mode Exit fullscreen mode

In the dataset, d.quantity is superior to two and it validates the condition. The report generated:
Alt Text

Iterate on attributes of objects

Printing an object as a list has never been easier, here is the dataset used for the following example:

{
  myObject : {
    paul : '10',
    jack : '20',
    bob  : '30'
  }
}
Enter fullscreen mode Exit fullscreen mode

The template used:
Iterate objects

First, the object have to be transformed to a list with d.myObject[i], then use .att to print the attribute or use .val to print the value.

The result:
Alt Text

Beta - supports dynamic charts rendering in XLSX files

The feature of printing charts is still experimental and will have improvements in the future. To make it work, the following steps have to be followed:

  • First, temporary data have to be inserted at the top left corner of the spreadsheet.
  • Then, the chart can be created from the temporary data range.
  • Replace the temporary data by the Carbone marker pointing to the JSON data set and add the formatter :formatN().

Here is a template example:
Alt Text
The dataset used:

{
  "list": [
    { "key": 1, "nbr": 2 }, 
    { "key": 2, "nbr": 3 }, 
    { "key": 3, "nbr": 1 }, 
    { "key": 2, "nbr": 4.4 }, 
    { "key": 5, "nbr": 10.01 }
  ]
}
Enter fullscreen mode Exit fullscreen mode

Here is the result:
Alt Text
Voila! πŸŽ‰

Conclusion

The community is positive and sharing good feedback about the latest release. All the changes and new features are available on the CHANGELOG.md.

Contact me if you need help with Carbone, I'll be happy to answer!

Thanks for reading!

Stay cool

Top comments (3)

Collapse
 
andresonax profile image
andresonax

Hello Steeve, I would like to insert a logo in my reports, is it possible via carboneJS?

Collapse
 
steeve profile image
Steeve

Hello @andresonax , It is available only on Carbone Render (API) or Carbone Studio (Web Interface to preview the report), not on the open-source version for now :)

Collapse
 
andresonax profile image
andresonax

From what I saw you are thinking of putting the image replacement in the open version. Is this really going to happen?