Nested loop in birt report

2.7k Views Asked by At

I'm using Eclipse Birt to generate report from a JSON File.

My JSON file look like this :

{  
"cells":[  
  {  
     "type":"basic.Sensor",
     "custom":{  
     "identifier":[  
           {  
              "name":"Name1",
              "URI":"Value1"

           },
           {  
              "name":"Name4",
              "URI":"Value4"
           }
        ],
        "classifier":[  
           {  
              "name":"Name2",
              "URI":"Value2"
           }
        ],
        "output":[  
           {  
              "name":"Name3",
              "URI":"Value3"
           }
        ],

     },
           "image":{  
           "width":50,
           "height":50,
           "xlink:href":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAYAAADDPmHLAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAABEJAAARCQBQGfEVAAAABl0RVh0U29mdHdhcmUAd3Vi8f+k/EREURQtsda2Or/+nFLqP6T5Ecdi0aJFL85msz2Qxyf4JIumMAx/ClmWt23GmL1kO54CXANAVH+WiN4Sx7EoNVkU3Z41BDHMeXAxjvOxNr7RJjzHX7S/jAflwBxkJr/RwiOpWZ883Nzd+Wpld7tkBr/SJr7ZHZbHZeuVweSnPfniocMAWYwcGBafH0OoPamFGAaY4ZBZjmmFGAaY4ZBZjmmFGAaY4ZBZjmmFGAaY7/B94QnX08zxKLAAAAAElFTkSuQmCC"
        }
     }
  },
  {  
     "type":"basic.Sensor",

     "custom":{  
        "identifier":[  
           {  
              "name":"Name1",
              "URI":"Value1"

           },
           {  
              "name":"Name4",
              "URI":"Value4"
           }
        ],
        "classifier":[  
           {  
              "name":"Name2",
              "URI":"Value2"
           }
        ],
        "output":[  
           {  
              "name":"Name3",
              "URI":"Value3"
           }
        ],

     },

        "image":{  
           "width":50,
           "height":50,
           "xlink:href":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAgAAAAIACAYAAAD0eNT6AAAACXBIWXMAAAsTAAALEwEAmpwYAAAKT2lDQ1BQaG90b3Nob3AgSUNDIHByb2ZpbGUAAHjanVNnVFPpFj333vRCS4iAlEtvUhUIIFJCi4AUkSYqIQkQSoghodkVUcERRUUEG8igiAOOjoCMFVEsDIoK2AfkIaKOg6OIisr74Xuja9igAQAAAgAIoAEAAAIACKABAAACAAigAQAAAgAIoAEAAAIACKABAAACAAigAQAAAgAIoAEAAAIADqhvprADeSsau00l5NAAAAAElFTkSuQmCC"
        }
     }
  },
  {  
     "type":"basic.Platform",

     "custom":{  
        "identifier":[  
           {  
              "name":"Name1",
              "URI":"Value1"

           }
        ],
        "classifier":[  
           {  
              "name":"Name2",
              "URI":"Value2"
           }
        ],
        "output":[  
           {  
              "name":"Name3",
              "URI":"Value3"
           }
        ],

        "image":{  
           "width":50,
           "height":50,
           "xlink:href":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAA6TH0jqtg6U8EsCdnm3SpevSK7Pb85xABEMBuLAn2hxjRve7SFzYEaB/HhytLQ4ABRwCWBPvBKnRk6U8EkBeOD9f7iwAGHAGEYEmwDxLvzNKfCCDP8NGLQd3lY7D0JwI4kmlwfHhX6dTSXxsRAAHsWR7aUjc7uM5Wg=="
        }
     }
  }
]
 }

i have 3 cells and each one contains 1 Image 1 Name 1 Type and 3 Tables , this is what i have done so far :enter image description here

what i'm struggling to do is a nested loop, i want to have for each object( Cell) in my JSON a paragraph numerated like this :

  • 2.x Component cell's Name :
    • Image
    • Output Table
    • Identifier Table
    • Classifier Table

So to do this i need to itterate on each cell and then itterate on each table Output, identifier and classifier and i have no idea how can i do this, a nested loop. like a List which represent the number of cells, that contains 3 tables, one image , one name.

**Edit : ** this is the open method for the data set

// Grab the JSON file and place it in a string
fisTargetFile = new FileInputStream(new File("C:/Users/Sample Reports/moe.json"));
input = IOUtils.toString(fisTargetFile, "UTF-8");

// Store the contents in a variable
jsonData = input;

// Convert the String to a JSON object
myJSONObject = eval( '(' + jsonData + ' )' );

// Get the length of the object
len = myJSONObject.cells.length;

// Counter
count = 0;

Fetch method :

if(count < len) {
var name     = myJSONObject.cells[count].attrs.text["text"];
var type    = myJSONObject.cells[count].type;
var icon =myJSONObject.cells[count].attrs.image["xlink:href"];



icon = icon.split(",");

icon= icon[1];
imageDataBytes = icon;

row["name"]     = name;
row["type"]    = type;
row["icon"]    = Base64ToBlob.toBytes(icon);



Logger.getAnonymousLogger().info( row["icon"]);
count++;
return true;
}

return false;
1

There are 1 best solutions below

1
On BEST ANSWER

You want to use nested tables, there is a good tutorial showing how to link nested tables to an outer table: please watch carefully this demo first, in particular see how the sub-table is linked to the outer table through a dataset parameter.

Of course your case is more challenging because you need to do this with scripted datasets and multiple sub-tables. I already did something similar, you have to create one scripted dataset for each sub-table. Key-points are:

  • In "parameters" section of each sub-dataset, create one input parameter and name it for instance "systemID"
  • Create your sub-tables by "drag & drop" each dataset within the outer table
  • In "bindings" section of each sub-table, link parameter "systemID" to the ID field of the outer table
  • In "open" event of sub-datasets, access the value of the parameter with this expression: inputParams["systemID"] Thus you can filter related rows in "myJSONObject".
  • It is important to make sure "myJSONObject" is initialized once for all, otherwise performances could dramatically decrease if it is evaluated on each iteration. For example evaluate it in "initialize" event of the report.

That's it, it won't be easy but these elements should help to achieve this report.