A report start band with the title, a grid header, a detail band, one group per category with its own header and footer, a summed subtotal, a report end band and a filter form.
A reportStart() band for the title and a reportEnd() band for the summary — once per report
A grid header, then a detail band rendered once per record
A group per category with its own header and footer bands
A subtotal per group via aggSum()
A filter form with typed controls (text, enum, number, relation)
One complete invoice per record, built from page blocks with declared heights. The Swiss QR payment slip stays on page 1 when it fits and moves to page 2 when the invoice positions need the space.
freeform() renders one complete form per detail record
Every section is an <x-reports::page-block> with a declared height
The payment slip is anchored with anchor="bottom": 105 mm from the paper edge, overlaying the footer
pageNumbering(perForm) restarts the page counter for every invoice
The page header with invoice number and customer is hidden on page 1
A block taller than the page body throws a BandOverflowException
Car purchase contract
· Free-form flow with general terms
One report, five source adapters: QuerySource, EloquentSource, RawSqlSource, CollectionSource and ArraySource all read the same SQLite table. Pick the adapter in the filter form.
A real SQLite table with demo orders, created by a migration
QuerySource and EloquentSource push filters and sorting into SQL
RawSqlSource, CollectionSource and ArraySource filter and sort in memory
The source selector is a normal typed filter control
Report start/end bands show the active adapter and the aggregated totals
Multilingual price list
· Pick language and format in the frame header
Flow
Language
Aggregates
/reports/multilanguage/run
Switch the language directly in the preview header. Report texts come from the module lang directory; dates and numbers follow the format locale, while the currency stays CHF.
Language selection in the report frame header
Module translations under app/Reports/Multilanguage/lang
Product, category and status texts come from language arrays in the source (like Spatie Translatable)
Dates and numbers follow the format locale (de_CH vs. en_US)
The currency stays CHF independently of the language
The switch applies to HTML preview and PDF
Grouped revenue with enrichment
· Group data from an Eloquent model
Flow
Groups
Language
Aggregates
Enrichment
/reports/group_enrichment/run
The detail rows come from demo_orders. Every group header loads its translated category name and target through enrichWith() from the demo_categories Eloquent model.
enrichWith() runs once per group, not per detail row
The group keys are passed to the enrichment source as filters
Eloquent returns the translated attribute because the engine set app()->getLocale()
The group data is available as $ctx->groupData() in header and footer bands
Group aggregate via $r->aggregate(..., scope: "group:1")
The language switch in the frame header affects category names and number formatting