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