# Creating reports in Jaspersoft Studio

<div style="text-align: justify;">

VeloxFactory renders reports defined as `.jrxml` files — the native format of JasperReports. These files are designed in **Jaspersoft Studio**, a free desktop IDE built specifically for this purpose. This page explains how to set up a `.jrxml` file so that VeloxFactory can analyse it correctly, register all its parts, and render it reliably.

[![jaspersoft-studio-overview.png](https://docs.veloxfactory.kiwi-software.dev/uploads/images/gallery/2026-05/scaled-1680-/jaspersoft-studio-overview.png)](https://docs.veloxfactory.kiwi-software.dev/uploads/images/gallery/2026-05/jaspersoft-studio-overview.png)

---

<h3 id="jaspersoft-studio" style="color: #203671; margin-top: 2.2em;">Jaspersoft Studio</h3>

Jaspersoft Studio is an Eclipse-based visual report designer. You use it to lay out the report template — define what data goes where on the page, how it is formatted, and which inputs the report expects. The resulting `.jrxml` file is then uploaded to VeloxFactory, which takes over everything from there: storing it, analysing it, connecting it to a data source, and rendering it on demand.

<div style="border-left: 4px solid #5fc75d; background: #f6fdf6; padding: 10px 16px; margin: 16px 0; border-radius: 0 4px 4px 0;">
ℹ️ <strong>Use version 6.21.5.</strong> This is the version compatible with VeloxFactory. Download it from the <a href="https://community.jaspersoft.com/download-jaspersoft/community-edition/jaspersoft-studio_windows_6.x" target="_blank">Jaspersoft Community</a>. Reports created with a significantly newer version may use features that VeloxFactory's render engine does not support.
</div>

The division of responsibilities between Jaspersoft Studio and VeloxFactory is clear:

- **Jaspersoft Studio** defines the layout, the parameters, the fields, and the visual design of the report.
- **VeloxFactory** manages the SQL query, the data connection, and the actual rendering at runtime.

This means you will see a `<queryString>` element in Jaspersoft Studio — but as explained [below](#the-query), you leave it empty. VeloxFactory supplies the query separately.

---

<h3 id="the-report-name" style="color: #203671; margin-top: 2.2em;">The Report Name</h3>

Every Jaspersoft Studio project has a **Report Name** — the `name` attribute on the root `<jasperReport>` element. This is not just a filename: VeloxFactory reads it directly from the `.jrxml` on upload and stores it as `report_name` on the `ReportConfig`.

```xml
<jasperReport ... name="A5_KanBan" ...>
```

This name must be **unique** across all report configurations in VeloxFactory. If you try to upload a `.jrxml` whose report name already exists, the upload will be rejected. The same applies to the file name itself.

<div style="border-left: 4px solid #203671; background: #f0f3fb; padding: 10px 16px; margin: 16px 0; border-radius: 0 4px 4px 0;">
⚠️ <strong>Set a descriptive, unique report name in Jaspersoft Studio before uploading.</strong> You can change it in Jaspersoft Studio via <em>File → Report Properties → Report Name</em>, or directly in the XML. Changing it after upload requires re-uploading the file.
</div>

[![jaspersoft-studio-report-properties.png](https://docs.veloxfactory.kiwi-software.dev/uploads/images/gallery/2026-05/scaled-1680-/jaspersoft-studio-report-properties.png)](https://docs.veloxfactory.kiwi-software.dev/uploads/images/gallery/2026-05/jaspersoft-studio-report-properties.png)

---

<h3 id="parameters" style="color: #203671; margin-top: 2.2em;">Parameters</h3>

Parameters are **input values** passed into the report at render time. They are used inside the report layout via `$P{PARAMETER_NAME}` expressions — for example to display a customer name in the title, filter by a date range, or pass a document number into a barcode expression.

You define parameters in Jaspersoft Studio via the **Report Inspector → Parameters** section. Each parameter has a name and a Java data type.

[![jaspersoft-studio-parameter-properties.png](https://docs.veloxfactory.kiwi-software.dev/uploads/images/gallery/2026-05/scaled-1680-/jaspersoft-studio-parameter-properties.png)](https://docs.veloxfactory.kiwi-software.dev/uploads/images/gallery/2026-05/jaspersoft-studio-parameter-properties.png)

<h4 style="color: #203671; margin-top: 1.4em;">Custom Properties: exampleValue and required</h4>

VeloxFactory reads two custom properties from each parameter definition: `exampleValue` and `required`. These are not standard Jaspersoft features — they are custom `<property>` elements you add manually to the parameter in the `.jrxml`. VeloxFactory's analyser (`JasperFunctions::analyzeReportFile`) extracts them on upload.

<table style="width: 100%; border-collapse: collapse;">
  <thead>
    <tr style="border-top: 1px solid #e6e8ef; border-bottom: 1px solid #e6e8ef;">
      <th style="text-align: left; padding: 6px 10px; white-space: nowrap;">Property</th>
      <th style="text-align: left; padding: 6px 10px;">Value type</th>
      <th style="text-align: left; padding: 6px 10px;">Purpose</th>
    </tr>
  </thead>
  <tbody>
    <tr style="border-bottom: 1px solid #e6e8ef;">
      <td style="padding: 6px 10px; white-space: nowrap;"><code>exampleValue</code></td>
      <td style="padding: 6px 10px;">string</td>
      <td style="padding: 6px 10px;">A representative value used when rendering a preview of the report without real data. Also pre-fills the parameter input in the frontend render form.</td>
    </tr>
    <tr style="border-bottom: 1px solid #e6e8ef;">
      <td style="padding: 6px 10px; white-space: nowrap;"><code>required</code></td>
      <td style="padding: 6px 10px;">boolean (<code>true</code> / <code>false</code>)</td>
      <td style="padding: 6px 10px;">Whether this parameter must be provided in every render request. VeloxFactory rejects render requests that are missing a required parameter.</td>
    </tr>
  </tbody>
</table>

Both properties can also be set or updated manually in VeloxFactory after upload — they do not have to come from the `.jrxml`. But embedding them in the file means they are automatically picked up every time the report is uploaded or re-uploaded.

To add these properties in Jaspersoft Studio, open the parameter in the **Report Inspector**, switch to the **Properties** panel, and add a new custom property via the green **+** button.

[![jaspersoft-studio-parameter-custom-properties.png](https://docs.veloxfactory.kiwi-software.dev/uploads/images/gallery/2026-05/scaled-1680-/jaspersoft-studio-parameter-custom-properties.png)](https://docs.veloxfactory.kiwi-software.dev/uploads/images/gallery/2026-05/jaspersoft-studio-parameter-custom-properties.png)

<h4 style="color: #203671; margin-top: 1.4em;">Supported Data Types</h4>

VeloxFactory supports the following Java class types for parameters. The type determines how the input field is rendered in the frontend and how the value is handled at render time.

<table style="width: 100%; border-collapse: collapse;">
  <thead>
    <tr style="border-top: 1px solid #e6e8ef; border-bottom: 1px solid #e6e8ef;">
      <th style="text-align: left; padding: 6px 10px; white-space: nowrap;">Java class</th>
      <th style="text-align: left; padding: 6px 10px;">Frontend input</th>
      <th style="text-align: left; padding: 6px 10px;">Notes</th>
    </tr>
  </thead>
  <tbody>
    <tr style="border-bottom: 1px solid #e6e8ef;">
      <td style="padding: 6px 10px; white-space: nowrap;"><code>java.lang.String</code></td>
      <td style="padding: 6px 10px;">Text field</td>
      <td style="padding: 6px 10px;">General-purpose text input</td>
    </tr>
    <tr style="border-bottom: 1px solid #e6e8ef;">
      <td style="padding: 6px 10px; white-space: nowrap;"><code>java.lang.Boolean</code></td>
      <td style="padding: 6px 10px;">Toggle</td>
      <td style="padding: 6px 10px;">Rendered as a checkbox/toggle switch</td>
    </tr>
    <tr style="border-bottom: 1px solid #e6e8ef;">
      <td style="padding: 6px 10px; white-space: nowrap;"><code>java.lang.Short</code></td>
      <td style="padding: 6px 10px;">Integer input</td>
      <td style="padding: 6px 10px;">Range: −32,768 to 32,767</td>
    </tr>
    <tr style="border-bottom: 1px solid #e6e8ef;">
      <td style="padding: 6px 10px; white-space: nowrap;"><code>java.lang.Integer</code></td>
      <td style="padding: 6px 10px;">Integer input</td>
      <td style="padding: 6px 10px;">Range: −2,147,483,648 to 2,147,483,647</td>
    </tr>
    <tr style="border-bottom: 1px solid #e6e8ef;">
      <td style="padding: 6px 10px; white-space: nowrap;"><code>java.lang.Long</code></td>
      <td style="padding: 6px 10px;">Integer input</td>
      <td style="padding: 6px 10px;">64-bit integer</td>
    </tr>
    <tr style="border-bottom: 1px solid #e6e8ef;">
      <td style="padding: 6px 10px; white-space: nowrap;"><code>java.lang.Float</code></td>
      <td style="padding: 6px 10px;">Decimal input</td>
      <td style="padding: 6px 10px;">Single-precision floating point</td>
    </tr>
    <tr style="border-bottom: 1px solid #e6e8ef;">
      <td style="padding: 6px 10px; white-space: nowrap;"><code>java.lang.Double</code></td>
      <td style="padding: 6px 10px;">Decimal input</td>
      <td style="padding: 6px 10px;">Double-precision floating point</td>
    </tr>
    <tr style="border-bottom: 1px solid #e6e8ef;">
      <td style="padding: 6px 10px; white-space: nowrap;"><code>java.math.BigDecimal</code></td>
      <td style="padding: 6px 10px;">Decimal input</td>
      <td style="padding: 6px 10px;">Arbitrary-precision decimal; preferred for monetary values</td>
    </tr>
    <tr style="border-bottom: 1px solid #e6e8ef;">
      <td style="padding: 6px 10px; white-space: nowrap;"><code>java.sql.Date</code></td>
      <td style="padding: 6px 10px;">Date picker</td>
      <td style="padding: 6px 10px;">Date only (no time)</td>
    </tr>
    <tr style="border-bottom: 1px solid #e6e8ef;">
      <td style="padding: 6px 10px; white-space: nowrap;"><code>java.util.Date</code></td>
      <td style="padding: 6px 10px;">Date picker</td>
      <td style="padding: 6px 10px;">Date only (no time)</td>
    </tr>
    <tr style="border-bottom: 1px solid #e6e8ef;">
      <td style="padding: 6px 10px; white-space: nowrap;"><code>java.sql.Time</code></td>
      <td style="padding: 6px 10px;">Time picker</td>
      <td style="padding: 6px 10px;">Time only (HH:mm)</td>
    </tr>
    <tr>
      <td style="padding: 6px 10px; white-space: nowrap;"><code>java.sql.Timestamp</code></td>
      <td style="padding: 6px 10px;">Date + time picker</td>
      <td style="padding: 6px 10px;">Combined date and time (datetime-local)</td>
    </tr>
  </tbody>
</table>

---

<h3 id="fields" style="color: #203671; margin-top: 2.2em;">Fields</h3>

Fields represent the **data columns** that populate the report's detail band — the repeating section that produces one row of output per data record. Each field corresponds to a column in the SQL query result (when using a live connection) or a key in the data array delivered at render time via the API.

You define fields in Jaspersoft Studio via the **Report Inspector → Fields** section. In the report layout, you reference them via `$F{FIELD_NAME}` expressions inside text fields in the detail band.

[![jaspersoft-studio-fields.png](https://docs.veloxfactory.kiwi-software.dev/uploads/images/gallery/2026-05/scaled-1680-/jaspersoft-studio-fields.png)](https://docs.veloxfactory.kiwi-software.dev/uploads/images/gallery/2026-05/jaspersoft-studio-fields.png)

<h4 style="color: #203671; margin-top: 1.4em;">Custom Property: exampleValue</h4>

Fields support one custom property: `exampleValue`. It works the same way as for parameters — a representative value used when rendering a preview of the report without a live data connection. VeloxFactory collects these example values and assembles a synthetic data row from them for preview rendering.

You add `exampleValue` to a field the same way as for parameters: open the field in the **Report Inspector**, go to the **Properties** tab, and add the custom property.

<div style="border-left: 4px solid #5fc75d; background: #f6fdf6; padding: 10px 16px; margin: 16px 0; border-radius: 0 4px 4px 0;">
ℹ️ <strong>Set meaningful example values for all fields.</strong> Without them, VeloxFactory cannot generate a preview or thumbnail for the report configuration. The values do not need to be real data — they just need to be type-compatible and representative enough to make the preview look sensible.
</div>

Fields support the same Java data types as parameters (see the table above). Use the type that matches the column type your SQL query or data array will produce.

---

<h3 id="parameters-in-sql" style="color: #203671; margin-top: 2.2em;">Using Parameters as SQL Variables</h3>

When a `ReportConfig` has a `ReportConnectionConfig` assigned, VeloxFactory executes the SQL query defined in the report configuration against that live database connection. Parameters passed in the render request are available as **named bindings** inside that query — using the standard `:parameterName` syntax from Laravel's Eloquent database layer.

This means you can reference any parameter directly in your SQL to filter, sort, or limit the result set:

```sql
SELECT
    article_number  AS articleNumber,
    description,
    moq,
    delivery_time   AS deliveryTime,
    supplier,
    barcode
FROM articles
WHERE article_number = :P_ARTICLE_NUMBER
```

In this example, `:P_ARTICLE_NUMBER` is replaced at query execution time with the value of the `P_ARTICLE_NUMBER` parameter from the render request. The binding is handled natively by PDO — values are passed as proper prepared statement parameters, not interpolated as strings.

<div style="border-left: 4px solid #5fc75d; background: #f6fdf6; padding: 10px 16px; margin: 16px 0; border-radius: 0 4px 4px 0;">
ℹ️ <strong>Only parameters that are actually referenced in the query are bound.</strong> VeloxFactory scans the query for <code>:name</code> placeholders before execution and silently drops any parameters that are not needed. Passing extra parameters in the render request will never cause a query error.
</div>

The parameter name in the query binding must match the parameter name exactly as defined in the `.jrxml` — including case. For example, a parameter named `P_ARTICLE_NUMBER` in the report must be referenced as `:P_ARTICLE_NUMBER` in the SQL query.

You can use as many parameters as needed across `WHERE`, `ORDER BY`, `LIMIT`, or any other clause that accepts a value binding. Note that named bindings cannot be used for identifiers like table or column names — only for values.

---

<h3 id="resources" style="color: #203671; margin-top: 2.2em;">Resources (Images and Logos)</h3>

If your report contains images — a company logo, a header graphic, a product photo — these are defined as **resource parameters** in the `.jrxml`. VeloxFactory detects them automatically on upload and creates a `ReportResource` record for each one.

The naming convention is strict: **every resource parameter must start with `P_RESOURCE_`** and must have the Java class `java.lang.String`. At render time, VeloxFactory replaces the parameter value with the actual file path of the uploaded image on the server.

```xml
<!-- Resource parameter: logo image -->
<parameter name="P_RESOURCE_LOGO" class="java.lang.String">
    <defaultValueExpression><![CDATA["C:/VeloxFactory/Logo_Dark.png"]]></defaultValueExpression>
</parameter>
```

In the report layout, you then bind this parameter to an image element:

```xml
<image>
    <reportElement x="460" y="100" width="84" height="50" uuid="..."/>
    <imageExpression><![CDATA[$P{P_RESOURCE_LOGO}]]></imageExpression>
</image>
```

The `<defaultValueExpression>` is used only in Jaspersoft Studio for design-time preview purposes. VeloxFactory ignores it at render time — it always uses the uploaded file path instead. You can point it to a local file on your design machine.

<div style="border-left: 4px solid #203671; background: #f0f3fb; padding: 10px 16px; margin: 16px 0; border-radius: 0 4px 4px 0;">
⚠️ <strong>Resource parameters are not treated as regular parameters in VeloxFactory.</strong> They do not appear in the Parameters section — they appear in the Resources section. You do not pass them in the render request; VeloxFactory fills them in automatically when rendering.
</div>

After uploading the `.jrxml`, you must go to the **Resources** section of the report configuration in VeloxFactory and upload the actual image file for each detected resource. A report cannot be rendered until all its resources have files assigned.

[![jaspersoft-studio-image-resource.png](https://docs.veloxfactory.kiwi-software.dev/uploads/images/gallery/2026-05/scaled-1680-/jaspersoft-studio-image-resource.png)](https://docs.veloxfactory.kiwi-software.dev/uploads/images/gallery/2026-05/jaspersoft-studio-image-resource.png)

---

<h3 id="detail-band" style="color: #203671; margin-top: 2.2em;">The Detail Band</h3>

The detail band is the repeating section of the report — the part that outputs one row per data record. If your report displays a list of items, a table, or any kind of repeating structure, it lives in the detail band.

VeloxFactory checks whether a detail band is present when analysing the `.jrxml`:

- If a detail band exists, VeloxFactory expects data to be provided at render time — either via a live SQL connection or via the `data` array in the API request.
- If no detail band exists, the report is treated as a **static layout** — no data is needed, only parameters.

<div style="border-left: 4px solid #203671; background: #f0f3fb; padding: 10px 16px; margin: 16px 0; border-radius: 0 4px 4px 0;">
⚠️ <strong>If you add a detail band, it must contain at least one text field element that uses a field expression (<code>$F{...}</code>).</strong> A detail band that exists but displays no field data will be rejected on upload. VeloxFactory uses the presence of text fields in the band as a basic integrity check.
</div>

Reports without a detail band are perfectly valid — they are useful for documents like cover pages, summary sheets, or any report whose content is entirely driven by parameters rather than repeated rows.

---

<h3 id="the-query" style="color: #203671; margin-top: 2.2em;">The SQL Query</h3>

Jaspersoft Studio has a built-in `<queryString>` element where you would normally write the SQL query for the report. **In VeloxFactory, this element is ignored.** The SQL query is instead defined and stored directly in VeloxFactory as part of the `ReportConfig` — not in the `.jrxml` file.

This means you should **leave the `<queryString>` empty** when creating a `.jrxml` for VeloxFactory:

```xml
<queryString>
    <![CDATA[]]>
</queryString>
```

You write the actual SQL query in VeloxFactory after uploading the report, in the **Query** field of the report configuration. This design keeps the query where it can be managed, versioned, and changed without touching the report template file.

The query result columns must match the field names you defined in the `.jrxml`. For example, if your report has a field named `articleNumber`, your SQL query must return a column called `articleNumber`.

---

<h3 id="data-adapter" style="color: #203671; margin-top: 2.2em;">The Data Adapter</h3>

Jaspersoft Studio uses **Data Adapters** to connect to a live database so you can preview your report during design. This is entirely a design-time feature — the data adapter you configure in Jaspersoft Studio has no effect in VeloxFactory and is not stored in the `.jrxml`.

At render time, VeloxFactory always uses its own internal array-based adapter to pass data to JasperReports. Whether that data comes from an SQL query executed against a `ReportConnectionConfig` or from a data array in the API request, VeloxFactory always handles the data handoff itself.

You still benefit from configuring a data adapter in Jaspersoft Studio during development — it lets you see a realistic preview while designing the layout. Just be aware that the adapter configuration stays local to your machine.

---

<h3 id="annotated-example" style="color: #203671; margin-top: 2.2em;">Annotated Example</h3>

The following is a complete, minimal `.jrxml` that demonstrates everything discussed on this page. It is the actual `A5_KanBan` report included in the VeloxFactory demo. Inline comments explain each relevant element.

```xml
<?xml version="1.0" encoding="UTF-8"?>
<!-- Created with Jaspersoft Studio version 6.21.5 -->

<jasperReport
    xmlns="http://jasperreports.sourceforge.net/jasperreports"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="..."

    name="A5_KanBan"         <!-- Report Name — becomes report_name in VeloxFactory. Must be unique. -->
    pageWidth="595"          <!-- Page dimensions in Jasper pixels (1px = 1/72 inch).              -->
    pageHeight="842"         <!-- VeloxFactory converts these to mm on upload.                       -->
    ...>


    <!-- ═══════════════════════════════════════════════════════════════════
         RESOURCE PARAMETER
         Name starts with P_RESOURCE_ and class is java.lang.String.
         VeloxFactory detects this as a resource (image/logo), not a parameter.
         The defaultValueExpression points to a local file for Studio preview —
         VeloxFactory replaces it at render time with the uploaded file path.
         ═══════════════════════════════════════════════════════════════════ -->
    <parameter name="P_RESOURCE_LOGO" class="java.lang.String">
        <defaultValueExpression><![CDATA["C:/VeloxFactory/Logo_Dark.png"]]></defaultValueExpression>
    </parameter>


    <!-- ═══════════════════════════════════════════════════════════════════
         REGULAR PARAMETER
         P_ARTICLE_NUMBER is a user-supplied input value passed at render time.
         exampleValue  → used for preview rendering and pre-fills the frontend form.
         required      → omitting this parameter in a render request will cause a 422 error.
         ═══════════════════════════════════════════════════════════════════ -->
    <parameter name="P_ARTICLE_NUMBER" class="java.lang.String">
        <property name="exampleValue" value="4561287-154"/>
        <property name="required"     value="true"/>
    </parameter>


    <!-- ═══════════════════════════════════════════════════════════════════
         QUERY STRING — leave empty.
         The SQL query is defined in VeloxFactory, not here.
         ═══════════════════════════════════════════════════════════════════ -->
    <queryString>
        <![CDATA[]]>
    </queryString>


    <!-- ═══════════════════════════════════════════════════════════════════
         FIELDS
         Each field maps to a column in the SQL result or a key in the data array.
         exampleValue → used for preview rendering when no live data is available.
         ═══════════════════════════════════════════════════════════════════ -->
    <field name="articleNumber" class="java.lang.String">
        <property name="exampleValue" value="1868745-584"/>
    </field>

    <field name="description" class="java.lang.String">
        <property name="exampleValue" value="Packing Carton Size 1 - 200x150x50mm"/>
    </field>

    <field name="moq" class="java.lang.Integer">
        <property name="exampleValue" value="250"/>
    </field>

    <field name="deliveryTime" class="java.lang.String">
        <property name="exampleValue" value="3 Days"/>
    </field>

    <field name="supplier" class="java.lang.String">
        <property name="exampleValue" value="Ninghao Packaging"/>
    </field>

    <field name="barcode" class="java.lang.String">
        <property name="exampleValue" value="5698532145712"/>
    </field>


    <!-- ═══════════════════════════════════════════════════════════════════
         DETAIL BAND
         The repeating section — one iteration per data row.
         Must contain at least one <textField> using a $F{...} expression,
         otherwise VeloxFactory rejects the file on upload.
         The image element uses $P{P_RESOURCE_LOGO} — VeloxFactory resolves
         this to the uploaded resource file at render time.
         ═══════════════════════════════════════════════════════════════════ -->
    <detail>
        <band height="167" splitType="Stretch">

            <!-- Field values referenced via $F{...} expressions -->
            <textField>
                <textFieldExpression><![CDATA[$F{articleNumber}]]></textFieldExpression>
            </textField>

            <textField>
                <textFieldExpression><![CDATA[$F{description}]]></textFieldExpression>
            </textField>

            <!-- Resource image: bound to the P_RESOURCE_LOGO parameter -->
            <image>
                <imageExpression><![CDATA[$P{P_RESOURCE_LOGO}]]></imageExpression>
            </image>

        </band>
    </detail>

</jasperReport>
```

<div style="border-left: 4px solid #5fc75d; background: #f6fdf6; padding: 10px 16px; margin: 16px 0; border-radius: 0 4px 4px 0;">
ℹ️ <strong>This example has been simplified for clarity.</strong> A real <code>.jrxml</code> contains many additional attributes, layout elements, and Studio-specific property annotations. The elements shown here are the ones VeloxFactory actively reads and acts on — everything else is passed through to JasperReports as-is.
</div>

---

<h3 id="checklist" style="color: #203671; margin-top: 2.2em;">Pre-Upload Checklist</h3>

Before uploading a `.jrxml` to VeloxFactory, verify the following:

- The **Report Name** (`name` attribute on `<jasperReport>`) is set, descriptive, and unique.
- All **resource parameters** follow the `P_RESOURCE_` naming convention and have class `java.lang.String`.
- All **regular parameters** have `exampleValue` and `required` custom properties set where applicable.
- All **fields** have an `exampleValue` custom property set.
- The **`<queryString>`** is empty — the SQL is managed in VeloxFactory.
- If the report has a **detail band**, it contains at least one `<textField>` with a `$F{...}` expression.
- The report **previews correctly in Jaspersoft Studio** using the local data adapter — this confirms the layout and expressions are valid before upload.

</div>