Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Report Generator Laravel Package

samuelterra22/laravel-report-generator

A Laravel package for generating reports from application data. Build report definitions from Eloquent queries or arrays and export results to common formats through a simple, fluent API, keeping reporting logic organized and reusable in your Laravel projects.

View on GitHub
Deep Wiki
Context7

Getting Started

This package wires report generation (CSV, Excel, PDF) into a Laravel app through a single Report abstraction, so the fastest path is:

  1. composer require samuelterra22/laravel-report-generator — note that v1.0.1 pins league/csv at ^9.7, so check your existing lockfile if you already depend on it directly.
  2. Publish the config: php artisan vendor:publish --tag=report-generator (or the package's config tag) to get config/report-generator.php. The config was tidied in 1.0.1 (blank-line cleanup only — no key changes), so a republish is safe but not required.
  3. Create a report class that extends the package's base Report, defining your data source, Blade view, and column headings.
  4. Register a route and return ->download() / ->stream() from the controller.

First use case to target: a single CSV export of one Eloquent model or query builder instance. CSV is the least-configuration output format — no maatwebsite/excel or dompdf dependency chain to debug — so it isolates package wiring from downstream library issues.

If you are upgrading from v1.0.0, do it now. The 1.0.1 fix (csv-report: use toString method for CSV caching) is a correctness fix: prior versions used a cast that does not reliably serialize the CSV writer's output into the cache, which can produce empty or truncated cached reports. Any endpoint serving cached CSV should be re-verified after the bump.

Implementation Patterns

One report class per business document. Treat the report class as a view model, not a generic exporter. It should own three things: the query, the presentation (headings, view), and the filename. This keeps route closures thin and makes the report testable and reusable across download() and stream().

Stream large exports, download small ones. download() typically buffers the whole file to build a response; stream() writes progressively. For anything user-generated or unbounded (order histories, audit logs), default to streaming and only switch to download when the file is predictably small.

Cache deliberately. CSV caching exists to avoid regenerating identical reports. Since 1.0.1 the cached payload is produced via toString, so the cache now stores actual serialized CSV content rather than a lossy string cast. Two implications for your code:

  • Cache keys need to encode the report's parameters (date range, filters, tenant). Two different filter sets must never collide.
  • Treat the cache as invalidated whenever underlying data changes. If your report is date-ranged, key on the range plus a data-version marker (e.g. max(updated_at)) rather than a TTL alone.

Separate the data layer from the format layer. Build a query or collection in the report class, and let the format-specific methods handle rendering. This lets the same report emit CSV for internal tools and PDF for customer-facing documents without duplicating filter logic.

Excel and PDF are opt-in. They drag in maatwebsite/excel and dompdf respectively. In applications that only need CSV, do not install the optional dependencies — you keep the dependency surface (and the security-update burden) small. Gate the routes accordingly.

Test via the HTTP layer, not internals. Assert on status code, Content-Type, Content-Disposition filename, and a couple of parsed rows from the response body. This catches the class of bug 1.0.1 fixed (empty cached body) without coupling tests to internal writer calls.

Feature-flag the rollout. Reports touch auth and data scope. Put the routes behind policies/middleware from day one — the package does not know who is allowed to see which rows, and a report route is a data-exfiltration surface if it accepts raw filter input from the query string.

Gotchas and Tips

CSV cache is the sharp edge. The 1.0.1 fix means cached output is now correct where it previously wasn't. If you had worked around the bug by disabling caching, you can re-enable it — but clear stale cache entries first, since pre-upgrade entries may be the malformed values.

Version conflict on league/csv. v1.0.1 requires ^9.7. If another dependency in your app pins an older 9.x or 8.x, Composer will either fail or silently keep the older package version alongside a newer release — check composer why league/csv after upgrading. This bump is the most likely reason an upgrade stalls in a real codebase.

Config caching hides config edits. After changing config/report-generator.php, run php artisan config:clear. Debug/verbose options read from a cached config will otherwise appear to have no effect and send you chasing a nonexistent bug.

Output-before-headers breaks downloads. Any stray echo, BOM, or debug dd() in a Blade view used by a report will corrupt the response, typically surfacing as a "headers already sent" warning or a file that opens as HTML. Keep report Blade views free of layout includes and whitespace outside the tags.

Memory, not CPU, is the failure mode. A report that works on 500 rows will exhaust memory on 50,000. Use chunk()/lazy() and cursor-style iteration in the query, and prefer stream() for these endpoints from the start.

PDF fonts and assets. Dompdf resolves fonts and images from filesystem paths, not URLs. Relative asset paths and storage_path() are reliable; asset() generally is not. Test PDF rendering on the server, not just locally.

Debug mode leaks data. If the config exposes a debug/verbose switch that dumps SQL or the report payload, ensure it is false in production and that the config is not committed with it enabled.

Extension points. The Blade view is the sanctioned customization surface — prefer overriding the view and headings over subclassing package internals, which will not survive minor releases. Keep any overridden methods thin and covered by a test so future changes to the base class surface as failures rather than silent regressions.

Upgrade cadence. The 1.0.x line is patch-only and the release notes for 1.0.1 contain no breaking changes: config edits are cosmetic, CI/dependency bumps are infrastructure, and the single behavioral change is the CSV caching fix. Safe to upgrade in a patch window; re-run your report integration tests afterward.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console