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

Excel Bundle Laravel Package

ticketpark/excel-bundle

Symfony bundle that wraps PHPExcel/PhpSpreadsheet, giving your app services and helpers to import and export Excel workbooks. Configure worksheets, cell styles, and data mappings through Symfony-friendly APIs for generating reports or reading uploaded spreadsheets.

View on GitHub
Deep Wiki
Context7

Getting Started

The bundle is a thin Symfony wrapper around HtmlPhpExcel (and, transitively, PHPExcel/PhpSpreadsheet). It turns an HTML <table> into a real .xlsx/.xls file, and its main value is letting you author spreadsheets with Twig templates instead of the Excel object model.

Install

composer require ticketpark/excel-bundle

Register the bundle in app/AppKernel.php (Symfony 2/3 style):

new Ticketpark\ExcelBundle\TicketparkExcelBundle(),

On modern Symfony check the package's composer.json constraint — this bundle predates Symfony Flex, so auto-registration and the exact PHPExcel/PhpSpreadsheet dependency usually need manual attention before it will install cleanly.

First place to look

  1. The bundle's Resources/config/services.xml — this tells you the service ID (typically ticketpark.excel) and which class it maps to.
  2. The class behind that service (usually Ticketpark\ExcelBundle\Service\ExcelFactory) — the public methods are what you'll actually call.
  3. The upstream HtmlPhpExcel README — the Symfony bundle re-exposes almost all of that API, so most documentation lives there.

First use case — a controller action that downloads a report

public function exportAction()
{
    $html = $this->renderView('AppBundle:Report:export.html.twig', [
        'rows' => $this->getDoctrine()->getRepository('AppBundle:Sale')->findAll(),
    ]);

    $excel = $this->get('ticketpark.excel');
    $excel->load($html);

    return $excel->createResponse('sales.xlsx');
}

Your Twig template simply renders <table> elements — no Excel-specific syntax is required. That mental model ("it's just HTML") is the whole package in one sentence.

Implementation Patterns

Render-to-HTML-to-Excel is the canonical flow. Keep the Twig template free of Excel-specific concerns. The template is also viewable in a browser, which makes iterating on the layout far faster than re-running the export.

Build a thin service, don't scatter calls. Wrap the bundle service in your own ReportExporter so the rest of the app doesn't depend on the bundle API directly. This pays off massively the day you need to swap HtmlPhpExcel for PhpSpreadsheet proper, or add caching, or gate feature flags.

class ReportExporter
{
    private $excel;

    public function __construct($excel)
    {
        $this->excel = $excel;
    }

    public function export(string $template, array $data): Response
    {
        $html = $this->templating->render($template, $data);

        return $this->excel->load($html)->createResponse('report.xlsx');
    }
}

Multi-sheet workbooks. HtmlPhpExcel lets you chain loads/sheets. The typical pattern is to render each Twig partial and add it as a named worksheet; useful for "Summary / Detail / Notes" style exports.

$excel->load($summaryHtml, 'Summary');
$excel->load($detailHtml, 'Detail');

Styling via CSS in the HTML. Set classes on <td>/<tr> and put the CSS inside a <style> block in the template. This keeps formatting declarative and testable. Only a subset of CSS properties is honored — see gotchas below.

Large exports — stream or background. For anything over a few thousand rows, don't render synchronously in a controller. Two workable patterns:

  • Chunked template rendering: render in batches of ~1000 rows and use the library's incremental load/save to a temp file, then stream the file.
  • Background job: queue an export, write to var/exports, email or poll for the result. This is the pattern most teams end up at for financial-style reports.

Integration with the frontend. Return the createResponse() directly for a download, or offer a POST endpoint that generates and returns a signed URL to the stored file. The latter is what you want behind auth-protected reports.

Testing. Because output is HTML → Excel, the fastest test loop is:

  1. Unit-test the template by asserting on rendered HTML (normal Twig tests).
  2. Integration-test the export by loading the result back with PhpSpreadsheet and asserting on cell values, not on the raw file bytes.

That two-layer approach catches both layout regressions and export bugs.

Gotchas and Tips

The dependency chain is old. HtmlPhpExcel was built against PHPExcel; the transition to PhpSpreadsheet has been messy. Expect to pin versions carefully. If composer require fails, inspect composer.json and the required PHPExcel/PhpSpreadsheet version, and consider whether a direct PhpSpreadsheet implementation plus a small HTML-to-sheet helper is a better long-term bet. This is the single biggest risk with this package.

CSS support is a subset, not a browser. You can rely on fonts, colors, backgrounds, borders, alignment and (sometimes) number formats on cells. Things like width on columns, text-overflow, media queries, and most pseudo-selectors are ignored. Debugging is by trial: put the property on the <td> and re-export.

Column widths often need explicit help. Set widths via the library API (or an inline attribute the library recognizes) rather than expecting CSS width to work. Auto-fit usually isn't automatic.

Dates and numbers. Excel treats strings that look like dates as strings. Force number formats by putting them in the CSS or by calling the API after load. The classic bug is a date column arriving as plain text and sorting alphabetically in the client.

Images must be reachable. Relative paths from your Twig template will silently fail because the HTML parser resolves them from the filesystem, not from the web root. Use absolute filesystem paths or data: URIs; the latter is more portable for tests.

Memory scales badly. PHPExcel/PhpSpreadsheet keeps the whole workbook in memory. A 50k-row export can push past memory_limit defaults. Either raise the limit and batch, or stream row-by-row. Watch that the HTML string itself is also in memory — render to a stream or temp file if the template output exceeds a few MB.

Template output must be well-formed. HtmlPhpExcel's parser is lenient but not forgiving of nested tables or unclosed tags — the output can be subtly wrong (cells shifted one column) rather than erroring. If results look misaligned, view-source the rendered Twig first; the bug is almost always there, not in the bundle.

The response class matters for downloads. createResponse($filename) sets correct content-type and disposition headers. If you build a Response yourself, forget the Content-Type/Content-Disposition headers and browsers will render garbage — use the helper.

Extension points to know. The bundle service is registered as a plain class; the easiest way to customise behavior is to decorate or extend that service (or your own wrapper) rather than editing vendor code. For response behavior, subclass the response helper; for factory behavior (e.g. caching rendered HTML), wrap the loader.

No async or queue support out of the box. If your product needs "email me when the export is ready", you're building that yourself. Budget for it up front on any report expected to exceed a few thousand rows.

Debugging tip. When an export looks wrong, save the rendered HTML to disk first:

file_put_contents('/tmp/report.html', $html);

Nine times out of ten the Excel output is accurately reflecting a broken template — this saves hours of blaming the library.

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