Report: grouped, summed and ready to export.
The report below runs in the sample app, published on the Online Test, on the same 52 sales. They appear grouped by salesperson, with subtotals per group and a grand total.
All the sales at once, split by salesperson
A report is a list view with grouping turned on and no pagination. All the records come out at once, split by group, with subtotals and the colored status.

Three properties turn the list view into a report
With three properties on the controller, the list view becomes a report. There is only one rule: the default sort (defaultSort) has to start with the grouping fields. If it doesn't, the same group shows up more than once.
class VendaReport extends MadDataGrid{protected string $model = Venda::class;// Sort MUST start with the grouping fields (otherwise groups repeat)protected string $defaultSort = 'vendedor ASC, data_venda ASC';public int $perPage = 0; // no pagination: whole groupsprotected string|array $groupBy = 'vendedor';protected bool $groupTotal = true;protected string $exportTitle = 'Sales Report';protected string $exportFilename = 'sales-report';} The export keeps the groups and subtotals
Groups, subtotals and the grand total go along to the CSV, the Excel file and the PDF. The PDF is the same one from the List view page, with header, breaks per group, colored status and Page X of Y.

When to use the report
Use the report when someone needs to see everything at once, split into groups and summed. It's the closing and reconciliation screen.
- Sales commission. The month's sales by salesperson, with each one's subtotal.
- Financial statement. Entries by account, with a balance that restarts on each account.
- Inventory movement. Stock in and out by product and, within it, by month.
- Support tickets. Tickets by technician, with each one's count.
To edit record by record, use the list view. For KPIs and charts, the dashboard. To print an order, the document. And the report's filters become regular Eloquent queries, as code generation shows.
What you configure
Besides the three properties above, these attributes change what shows on screen and in the PDF.
- Grouping levels
group-by - Up to three fields, separated by commas. It accepts a field from another table and a date grouped by day, month or year.
- Group label
group-mask - The text that opens each group, with fields and values already formatted, such as currency and date.
- Aligned subtotal
group-band - With the
cellsvalue, subtotals sit under the summed columns, as in a printed report. - Detail row
row-detail - A second row under each record, such as an entry's history. It shows on screen and in the PDF.
- Running balance
running - Adds up the column row by row. With
running-reset="group", the balance restarts on each group. - File subtitle
export-subtitle - It can carry the filtered period. That way the PDF already says what dates the numbers cover.
What goes into the Laravel project
The report uses the same base as the list view (MadDataGrid), in a class in app/Control with the <mad-grid> view. What you adjust in code:
- Tweaks in PHP properties. Grouping, subtotal, title and file name are class properties. If the Blade sets the title attribute, it wins.
- Extra filter in Eloquent. A condition the screen doesn't offer goes into the class's search method (
onSearch). - PDF header with placeholders. The PDF bands live in a block of the class, with title, date, period, active filters and page number. A value specific to this screen comes in through its own method (
exportPdfPlaceholders).
Like every MadBuilder screen, these files open in your editor, go into your Git and accept hand-written code in protected blocks, which stay there when the screen is regenerated. See how the code is generated.
Questions about the report
Can I group the report by more than one field?
Yes, up to three levels, such as salesperson and then month. Each level gets its own group band.
Can I group by a field from another table?
Yes, when each record points to a single item in the other table, like a sale and its customer. Not through a sale's payments, because there are several.
Why does the report have no pagination?
With pagination, a group would be cut in the middle and the subtotal would only add up the part on the page. On large datasets, you can require users to filter before running the query.
And more
Create an account, build a screen, download the project.
No scheduled demo, no discovery call. If the Laravel that comes out doesn’t pass your team’s review, you lost an afternoon.
- Create an accountOpen beta, no credit card.
- Build a screenVisually, in code, or by asking the AI.
- Download the .zipA Laravel project that runs wherever you want.