Report types

Three shapes cover most printed output: a column list, a banded list and a single form. All of them use the same band model.

Flow mode

Chromium paginates the content. Bands flow naturally and page breaks are inserted where the content runs out of space. This is the default.

Strict mode

Every band has a fixed height and pages are filled arithmetically. Ideal for forms, labels and anything that must land on an exact position.

List

A detail band repeated per record, optionally grouped with headers, footers and aggregates.

<?php

declare(strict_types=1);

namespace App\Reports\PriceList;

use App\Reports\Layout\CompanyLayout;
use Guggach\Reports\Definition\ReportBuilder;
use Guggach\Reports\Filters\FilterBuilder;
use Guggach\Reports\Report as BaseReport;
use Guggach\Reports\Sources\ReportSource;

final class Report extends BaseReport
{
    public function key(): string
    {
        return 'price_list';
    }

    public function name(): string
    {
        return 'Preisliste';
    }

    public function layout(): string
    {
        return CompanyLayout::class;
    }

    public function source(): ReportSource
    {
        return new Source;
    }

    /**
     * Demonstrate the fluent control description: operator listbox for the
     * number, multiselect for the enum and a searchable dual-list for the
     * relation (id/FK) field.
     */
    public function filterControls(): array
    {
        return FilterBuilder::for($this->source())
            ->field('price')->operators(['=', '>=', '<=', 'between', 'in'])
            ->field('category')->multiselect()
            ->field('supplier')->picker(valueField: 'id', labelField: 'label')
            ->build();
    }

    public function define(ReportBuilder $r): void
    {
        // Module-relative view names resolve to app/Reports/PriceList/views/*.
        // Report start/end run once per report; the grid header introduces the
        // table and the detail band renders one row per record.
        $r->reportStart(view: 'report-start');
        $r->gridHeader(view: 'grid-head');
        $r->detail(view: 'row');
        $r->reportEnd(view: 'report-end');

        // Grouped by category (data is sorted by category) with a subtotal.
        $r->group('category', function ($g): void {
            $g->header(view: 'category-head');
            $g->footer(view: 'category-foot');
            $g->aggSum('price', as: 'category_total');
        });
    }
}

Single form

One form per record, repeated per data set, with its own page counter.

Next · Bands explained See which band runs when — and how the engine repeats the stack across pages.