Skip to main content

Advanced Reporting

Once the basic report flow is working, the next step is usually one of these advanced patterns:

  • group rows into logical sections,
  • render related child data through subreports,
  • nest subreports further,
  • display dynamic images such as customer logos.

Groups

Groups are the right tool when the main dataset should be visually partitioned by a repeated key such as ORGID, CONTACTID, or another parent identifier.

Typical use case:

  • one dataset contains both organisation rows and person rows,
  • the report groups by ORGID,
  • company information is shown in the Group Header,
  • person-specific information is shown in the Detail band.
  • Group by stable technical identifiers, not by display labels.
  • Put parent-level information into Group Header.
  • Put child-level repeating information into Detail.
  • Use Group Footer only when you really need separators, subtotals, or summaries.

If the required data still lives in one flat dataset, prefer groups before reaching for subreports.

Subreports

Subreports are useful when a report needs to display related datasets that should keep their own layout and iteration behavior.

Typical cases:

  • a company with all employees,
  • a person with all communication entries,
  • a document with repeating line items and further detail blocks.

ADITO-specific subreport handover

For ADITO to recognize a subreport dataset, the master report needs a parameter whose name starts with adito.datasource..

Example:

adito.datasource.subdataCOMM

The parameter class must be Object, and the subreport's Datasource Expression typically points to it:

$P{adito.datasource.subdataCOMM}

Passing subreport data from JDito

import { ReportData } from "Report_lib";
import { newSelect } from "SqlBuilder_lib";

const subreportData = new ReportData(["COMMID", "CONTACTID", "MEDIUM", "ADDR"]);

const commData = newSelect(
"COMMUNICATION.COMMUNICATIONID, COMMUNICATION.CONTACT_ID, COMMUNICATION.MEDIUM_ID, COMMUNICATION.ADDR"
)
.from("COMMUNICATION")
.table();

subreportData.add(commData);
report.addSubReportData("subdataCOMM", subreportData);

addSubReportData("subdataCOMM", ...) maps the dataset to the Jasper parameter adito.datasource.subdataCOMM.

Filtering subreport rows correctly

Passing the full child dataset is only the first step. The subreport still needs to know which rows belong to the current master row.

Common pattern:

  1. Add a parameter in the subreport, for example FILTER_CONTACTID.
  2. In the master report, pass the current field value into that parameter.
  3. In the subreport, use a Filter Expression such as:
$P{FILTER_CONTACTID}.equals($F{CONTACTID})

Without this filter, each master row may render the complete child dataset.

Nested subreports

Use nested subreports only when the document structure really requires "details of details", for example:

  • organisations
  • persons belonging to those organisations
  • history entries belonging to those persons

The same rule applies again: data from the higher-level report must be forwarded via parameters, and each nested report must receive only the part of the data that belongs to the current parent row.

Dynamic images

ADITO supports two common image patterns in JasperReports.

Images passed as report parameters

If the image is passed as a report parameter, its parameter name must start with adito.image. so ADITO recognizes it as image data.

Example:

adito.image.companyLogo

These parameters typically contain a Base64-encoded image string.

Images stored in fields

For dataset-specific images such as a company logo per record, a field-based approach is often more suitable.

Typical image expression:

new ByteArrayInputStream(new Base64().decodeBase64($F{fieldName}.getBytes("UTF-8")))

Typical expression class:

java.io.InputStream

To use that expression, import:

org.apache.commons.codec.binary.Base64

Important image note

If the source value already includes a prefix such as data:image/png;base64,, strip that prefix before passing the raw Base64 data into the report field or parameter.

If an image may be empty, set the image element's error handling to a blank behavior so missing images do not break report rendering.

When to use which technique

Use this rule of thumb:

  • Groups for one flat dataset with logical parent-child sections
  • Subreports for multiple related datasets with distinct layouts
  • Nested subreports only for genuinely deep document structures
  • Dynamic images for record-specific branding or visual status output