Craft CMS 5 · Lab Reports compatible
Reports that ask before they run
Lab Reports was a good plugin that stopped getting new features, and its issue tracker reads like a to-do list: parameters, more formats, files that survive a redeploy, exports that don't time out. Reportr does all of it, and your existing report templates run unchanged.
The template you already have, with parameters it never had
The same `report` variable and the same `build()` signatures as Lab Reports. Parameters arrive already typed — a date is a `DateTime`, an entries parameter is an entry — and a default of `-7 days` means the last seven days from each run, which is what makes a scheduled report worth scheduling.
{# Parameters: since (date, default "-7 days"), customer (users) #}
{% set query = craft.orders.isCompleted(true).orderBy('dateOrdered') %}
{% if params.since %}
{% set query = query.dateOrdered('>= ' ~ params.since|date('Y-m-d')) %}
{% endif %}
{% if params.customer %}
{% set query = query.customer(params.customer) %}
{% endif %}
{# An unexecuted query: Reportr walks it in batches and streams to disk. #}
{% do report.build(['Order', 'Date', 'Email', 'Total'], query) %}
Features
Everything on Lab Reports' roadmap, and the things nobody had filed yet.
Drop-in for Lab Reports
Templates and formatting functions unchanged — Reportr reads config/labreports.php too. One importer brings the configurations and the whole run history across with their files, never touches the old tables, and is safe to run twice.
Run-time parameters
Text, numbers, dates, yes/no, dropdowns, checkboxes, entries, users, categories, assets, tags and sites — asked in the control panel, passed on the command line, or defaulted for a schedule. Relative defaults like -30 days.
Reports with no template
Pick an element type, one of its own index sources and the columns from a list. Dotted keys reach into related elements and Table fields, so "members who joined last month" is not a deployment.
Seven formats
CSV, TSV, a real XLSX workbook, JSON, NDJSON, XML and a self-contained HTML table — plus your own writer class. Spreadsheet formula injection is neutralised by default.
Any filesystem
Write to S3, Spaces or any Craft filesystem, so reports survive Heroku, scaled containers and read-only images. Each run remembers where it went, so changing the default never orphans the archive.
Scheduled and delivered
Hourly, daily, weekly or monthly in the site's timezone, claimed so two schedulers can't both fire. Email every run, only successes, or only failures — the run that matters is the one that didn't work.
Big reports, bounded memory
Rows stream from a batched query to a file handle; the queue timeout is an hour, not 300 seconds. Every run records its duration and peak memory, and a build that dies is marked failed with the reason.
Preview before you run
See the first rows, with the parameters you chose, without writing a file or waiting for the queue — the end of save, run, download, squint, repeat.
Permissions that respect content
Seeing a report and downloading its output are separate permissions. Someone who isn't an admin can only report on sources they can already see in the control panel.
Frequently Asked Questions
What people ask before moving their reports.
No. Basic and advanced reports call the same methods on the same report variable, and your formatting functions keep working where they are. Front-end templates need one find-and-replace: craft.labreports becomes craft.reportr.
Never. It only reads them, so you can compare the two side by side before uninstalling anything, and running it twice skips everything already brought across.
$29 per site, including a year of updates, then $19 a year. One edition — everything is included.
No. Reportr writes the workbook itself and streams it, so it has no dependencies beyond PHP's zip extension, and only for that format.
Reportr raises the queue job's timeout to an hour by default (configurable) and streams rows to disk in batches, so a report is bounded by disk rather than memory.
Yes — any Craft filesystem, per report or site-wide. Builds write locally and move the finished file into place, so nothing downstream ever sees half a file.
Each run's page plots row counts across recent runs, and the HTML format is there for reports meant to be read. Charts inside a report are deliberately left to the spreadsheet.
It works without one, firing from control-panel traffic like Craft's own queue. For a report that must run on Monday at 07:00, add php craft reportr/schedule/run every minute.
Move your reports in an afternoon
Install it next to Lab Reports, dry-run the import, compare, and switch. $29 per site.