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

fungio/excel-bundle

A Symfony bundle that integrates PhpSpreadsheet into your application, providing ready-to-use services and configuration for reading, writing, and exporting Excel spreadsheet files with less boilerplate. Useful for importing data or generating reports.

View on GitHub
Deep Wiki
Context7

Getting Started

First, set expectations. This bundle wraps PHPExcel (abandoned since 2017, superseded by PhpSpreadsheet) for a Symfony2 app (EOL since 2018). It has 1 star and 0 dependents, meaning no community, no issue triage, and no compatibility work. Treat it as legacy-maintenance only: if you're starting greenfield, skip this and use PhpSpreadsheet directly.

Minimal steps for a legacy Symfony2 app:

  1. composer require fungio/excel-bundle (older docs may say fungio/excelbundle — check what Packagist resolves, since some bundles shipped PHPExcel inside vendor/ rather than as a Composer dep).
  2. Register the bundle in app/AppKernel.php:
    $bundles = array(
        // ...
        new Fungio\ExcelBundle\FungioExcelBundle(),
    );
    
  3. Look first at Resources/config/services.yml inside the bundle and the bundle's DependencyInjection/ folder. The service ID is the whole API surface — this bundle is a thin factory around PHPExcel, PHPExcel_IOFactory, and the writer/reader classes. Confirm the ID with php app/console container:debug | grep -i excel before writing any controller code.
  4. First use case: export a Doctrine result set to .xlsx from a controller. That's the 90% case and the fastest path to validating the install.
// app/config/config.yml — only if the bundle exposes config keys (check the DI Extension class)
fungio_excel: ~

If the service ID isn't obvious, you can bypass the bundle entirely — PHPExcel is autoloadable once installed, and the bundle adds little beyond wiring:

$objPHPExcel = new \PHPExcel();
$sheet = $objPHPExcel->setActiveSheetIndex(0);
$sheet->setCellValue('A1', 'Name')->setCellValue('B1', 'Total');

Implementation Patterns

Pattern 1 — Streamed xlsx export (most common).

Build the sheet, write to php://output, set headers, exit. Never write to a temp file and readfile() unless you need the file afterwards.

public function exportAction()
{
    $phpExcel = $this->get('fungio_excel')->createPHPExcelObject(); // verify ID
    $sheet = $phpExcel->setActiveSheetIndex(0);

    $row = 1;
    $sheet->fromArray(array('Id', 'Name', 'Total'), null, 'A' . $row++);
    foreach ($this->getDoctrine()->getRepository('AppBundle:Order')->findAll() as $order) {
        $sheet->fromArray(array(
            $order->getId(), $order->getName(), $order->getTotal(),
        ), null, 'A' . $row++);
    }

    $writer = $this->get('fungio_excel')->createWriter($phpExcel, 'Excel2007');
    $response = $this->get('fungio_excel')->createStreamedResponse($writer);
    $response->headers->set('Content-Type',
        'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
    $response->headers->set('Content-Disposition', 'attachment; filename="orders.xlsx"');
    return $response;
}

Use fromArray() for row data instead of per-cell setCellValue() — it's dramatically faster and less error-prone than column math.

Pattern 2 — Template fill. Store a formatted .xlsx in app/Resources/, load it with the Excel2007 reader, write values into named cells, then save. This preserves styling, merged cells, and column widths that you cannot reasonably reproduce in code. It's the single best reason to keep PHPExcel around.

Pattern 3 — Import with read filters. For anything over a few thousand rows, do not load the whole file. Use setReadDataOnly(true) plus a chunked PHPExcel_ReadFilter implementing IReadFilter::readCell($column, $row, $sheet), loop through row windows, and $phpExcel->disconnectWorksheets(); unset($phpExcel); between chunks. Persist entities with an EntityManager::flush()/clear() every 200–500 rows.

Pattern 4 — Background jobs. Any export larger than ~5k rows belongs in a ContainerAwareCommand writing to a file, with the controller just serving the finished file. Requests that hold a large workbook in memory will blow memory_limit and time out under load.

Pattern 5 — PDF. PHPExcel's PDF writer is just a renderer shim: PHPExcel_Settings::setPdfRendererPath() / setPdfRendererName() pointing at a dompdf/mpdf/tcpdf install. In practice this path is fragile and poorly maintained — if PDF output matters, render HTML with a maintained Twig-to-PDF library instead.

Gotchas and Tips

  • PHP version cliff. PHPExcel breaks on PHP 7.2+ (each(), curly-brace string offsets, PHPExcel_Shared_String assumptions). If you're on PHP 7.2 or newer, this package cannot work without patches. Pin PHP 7.1 or migrate to PhpSpreadsheet — this is the deciding factor, not the bundle itself.
  • Symfony compatibility ceiling. Symfony2 bundle conventions (AppKernel, YAML service defs, getContainer() injection patterns) generally won't load cleanly on Symfony 3.x+, and definitely not 4+. You are choosing between "stay on Symfony 2" and "don't use this."
  • Memory. A 1 MB .xlsx routinely consumes 30–80 MB in PHPExcel. Mitigations: PHPExcel_Settings::setCacheStorageMethod(PHPExcel_CachedObjectStorageFactory::cache_to_discISAM) (requires php.ini temp dir writable), setReadDataOnly(true), and explicit disconnectWorksheets() + unset() in loops.
  • Dates are serials. Imported date cells return floats (e.g. 43831), not DateTime. Convert with PHPExcel_Shared_Date::excelToDateTimeObject($value) and check PHPExcel_Date::isDateTime($cell) first, or you'll write garbage into date columns.
  • Formulas read as strings. getValue() returns "=SUM(A1:A9)", not the result. getCalculatedValue() exists but is slow and needs a full recalculation pass — cache results at import time if you rely on them.
  • Row/column indexing off-by-one. getCell('A1') is 1-based; getCellByColumnAndRow(0, 0) is 0-based. Mixing the two silently shifts data by one row/column. Standardize on fromArray()/toArray().
  • getHighestRow() lies. It includes rows containing only styling or stray whitespace, so imports often run thousands of empty iterations. Always check whether the row's first cell is non-empty before processing.
  • Output ordering. Anything echoed before the writer runs (a stray var_dump, a close ?> tag with trailing newline, a BOM) corrupts the .xlsx and produces "file is corrupt" in Excel. Write to php://output last and exit immediately.
  • Temp files. The writer uses sys_get_temp_dir(); on locked-down hosts this may be unwritable or fill up. Make it configurable and clean up after streamed responses.
  • CSV import encoding. Excel's "CSV" is frequently Windows-1252 with ; delimiters. setInputEncoding('CP1252') and a delimiter sniff are usually required; the reader will not guess.
  • Extension points are thin. The bundle offers little beyond service wiring — forking is often easier than extending. If you need custom behavior (custom cell formats, event hooks), go straight to PHPExcel/PhpSpreadsheet primitives rather than fighting the bundle's abstractions.

Verdict for day-to-day work: usable only as a stopgap in an existing Symfony2 codebase that already depends on it. For new code, PhpSpreadsheet plus a small service of your own gives you the same functionality with an actively maintained library, PHP 8 support, and a community to search when something breaks.

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.
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle