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

Twig Spreadsheet Bundle Laravel Package

mattfanz/twig-spreadsheet-bundle

A Symfony bundle that brings spreadsheet generation into Twig templates, letting you build and render Excel-style documents directly from your views with minimal PHP boilerplate. Useful for exports, reports, and downloadable data files.

View on GitHub
Deep Wiki
Context7

Getting Started

Read this first: it is a Symfony bundle, not a Laravel package. With 1 star, 0 dependents, and a near-zero adoption score, treat it as a reference implementation or a short-lived dependency rather than a foundation. Before writing any code, spend ten minutes on the repo: check the last commit date, the composer.json constraints (symfony/framework-bundle, phpoffice/phpspreadsheet, PHP version), whether there are tags/releases, and whether the README’s API matches the code in src/. If the constraints exclude your Symfony/PHP version, stop and vendor the useful classes instead.

Minimal steps in a Symfony app:

  1. composer require mattfanz/twig-spreadsheet-bundle (pin an exact version; there is no ecosystem pressure keeping it compatible).
  2. Register the bundle in config/bundles.php (new MattFanz\TwigSpreadsheetBundle\TwigSpreadsheetBundle() — confirm the real FQCN in the repo’s src/), or let Flex do it if a recipe exists (unlikely).
  3. Inspect DependencyInjection/ and Resources/config/ to learn the actual service IDs and configuration tree. Do not trust the README alone; the service definitions are the source of truth.
  4. Run bin/console debug:container --show-private | grep -i spreadsheet and debug:config for the bundle alias to see what you actually got.
  5. bin/console lint:twig templates/ to confirm the Twig extension is registered.

Where to look first: the Twig extension class (usually Twig/Extension/*Extension.php) tells you the exact function/filter names and signatures. That is your real API documentation. The bundle’s factory/service is what you inject into controllers or exporter services.

First use case: a controller that builds a workbook, streams it as an .xlsx response, and uses a Twig template for headers/labels so non-developers can tweak column titles. Confirm the round trip works end to end (open the file in LibreOffice, not just Excel) before building anything larger.

If you are actually working in Laravel: you cannot register a Symfony bundle in a Laravel kernel. Either copy the Twig extension and factory classes into app/Support/ and wire them manually, or skip this package and use phpoffice/phpspreadsheet directly (or maatwebsite/excel). The bundle gives you almost nothing beyond service wiring and a few Twig functions, and you can reproduce that in an hour.

Implementation Patterns

Inject the factory, keep templates dumb. The clean pattern is a dedicated SpreadsheetExporter service that receives the bundle’s factory/workbook service, builds sheets programmatically, and only delegates labels and small layout decisions to Twig. Do not try to express workbook structure (merged ranges, formulas) in Twig; it becomes unreadable and untestable fast.

Controller → StreamedResponse. Build the workbook, write to php://output via PhpSpreadsheet\Writer\Xlsx, and return a StreamedResponse with Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet and a Content-Disposition filename. Set ob_end_clean()/flush() carefully; stray output corrupts the binary.

Twig-assisted generation. Where the bundle exposes a render-to-spreadsheet path, the workflow is: render a Twig template to a string, parse the rows (CSV/HTML/whatever the bundle supports), and hand them to PhpSpreadsheet. Use it for report headers, footers, and translation strings — not for the data loop. Verify what the Twig functions actually return before designing around them.

Reusable exporter services. Define an interface (SpreadsheetExporterInterface::export(ReportData $data): Workbook), one implementation per report, and tag them. This lets you swap the bundle out later without touching controllers — important given the maintenance risk.

Queue large exports. Anything over a few thousand rows should go through a messenger job that writes to storage and emails a link. PhpSpreadsheet holds the whole workbook in memory; a synchronous request will time out or exhaust memory_limit.

Integration tips. Check whether the bundle autowires aliases; if not, bind the concrete service ID in services.yaml. Use %kernel.cache_dir% or a dedicated temp directory for any intermediate files, and make it configurable via the bundle config or your own parameter. In tests, assert on cell values via $sheet->getCell('A1')->getValue() rather than byte-comparing files.

Gotchas and Tips

  • Abandonment is the primary risk. One star and zero dependents means no one will notice a broken release. Pin the version, commit the lock file, and be prepared to fork. If the bundle is a thin wrapper, fork it into src/ and delete the dependency.
  • Symfony version drift. Old bundles often use service definition syntax or bundle extension patterns that break on newer Symfony majors. debug:container and cache:clear are your first diagnostics; a ServiceNotFoundException usually means the bundle wasn’t registered or the config key is wrong.
  • Twig whitespace will bite you. Template newlines and indentation can become blank rows or cells in generated files. Use {%- -%} trimming and test with a tiny fixture.
  • Autoescaping is irrelevant but harmless for spreadsheet values; however HTML entities (&) may leak into cells if data is rendered through Twig. Disable escaping for data values.
  • Dates and formulas. PhpSpreadsheet stores dates as serial numbers; Twig-rendered strings won’t be typed as dates. Set explicit number formats, and remember formulas aren’t recalculated until opened unless you force setPreCalculateFormulas(true) on the writer.
  • Memory and time. Use --memory-limit=-1 for CLI exports and consider Settings::setCache for large workbooks. Xlsx is the heaviest writer; CSV is far cheaper if the consumer doesn’t need formatting.
  • Binary output corruption. Any echo, warning, or BOM before the writer runs produces a file Excel refuses to open. Wrap generation in output buffering and log instead of printing.
  • Laravel mismatch. Symfony bundles do not load in Laravel. Do not add this to a Laravel composer.json expecting services; you’ll get classes but no wiring. Copy the Twig extension and register it with Laravel’s Twig bridge (if you use one), or just use PhpSpreadsheet with Blade.
  • Extension points. The realistic ones are: a custom Twig extension that calls the bundle’s factory, decorating the factory service, and a compiler pass to tag exporters. Don’t subclass bundle internals — they’re unstable.
  • Debugging checklist: debug:container for the service, lint:twig for the extension, a one-cell fixture for the writer, and LibreOffice for the file itself. If all four pass, the problem is your data, not the bundle.
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.
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin