PHP Classes

How Can a PHP Library Excel Export and Read Be Very Fast Using the Package Easy-Excel: Export and read XLSX files with a PHP Go extension

Recommend this page to a friend!
  Info   Documentation   View files Files   Install with Composer Install with Composer   Download Download   Reputation   Support forum   Blog    
Last Updated Ratings Unique User Downloads Download Rankings
2026-07-31 (21 hours ago) RSS 2.0 feedNot yet rated by the usersTotal: Not yet counted Not yet ranked
Version License PHP version Categories
easy-excel 1.0BSD License7Files and Folders, Parsers, PHP 7, Bu...
Description 

Author

This package can export and read XLSX files with a PHP Go extension.

It provides a PHP extension written in the Go language that implements classes compatible with the PhpSpreadsheet package.

This package can be used with the Easy Excel polyfill package to provide a solution to read and write Excel packages in a way that will work even when the Easy Excel extension is not available.

Innovation Award
PHP Programming Innovation award nominee
July 2026
Nominee
Vote
Microsoft Excel is a popular spreadsheet tool.

Applications that want to provide or process spreadsheet files that can be used with the Excel tool can use the format XLSX.

This package provides a PHP extension that can read and export XLSX files very fast in a way that is compatible with the PHPSpreadsheet package.

Manuel Lemos
Picture of Roni
  Performance   Level  
Name: Roni <contact>
Classes: 13 packages by
Country: Bangladesh Bangladesh
Innovation award
Innovation award
Nominee: 7x

Instructions

Documentation

easy-excel

A PHP spreadsheet extension written in Go for FrankenPHP, exposing a PhpSpreadsheet-compatible API while doing all heavy lifting (XML generation, ZIP compression, parsing, formulas) in compiled Go via excelize.

Target: PhpSpreadsheet's ergonomics at OpenSpout-class (constant) memory and a multiple of both libraries' throughput. Design rationale, bottleneck analysis and measured claims live in PLAN.md; API coverage in COMPAT.md; formula coverage in FORMULAS.md; the raw extension API (no composer package needed) in NATIVE.md; known gaps in MISSING.md.

How it works

PhpOffice\PhpSpreadsheet\* (aliases)        ? your existing code, unchanged
        ?
EasyExcel\Compat\* PHP shim                 ? tiny objects, write-behind row buffer
        ?  flat easy_excel_*() calls, batched rows (1 CGO call / 512 rows)
Go extension: handle registry ? excelize    ? StreamWriter, style interner,
                                              admission control, path policy

Key properties:

  • Dual write path ? sequential writes stream at constant memory; an out-of-order write triggers a one-time documented fallback to random access.
  • Load control ? heavy operations pass a weighted semaphore + memory budget; overload surfaces as `EasyExcel\Exception\Overloaded` (map it to HTTP 429 or your queue) instead of OOM-killing the worker.
  • Security defaults ? unzip-bomb limits, path allowlist (`EASY_EXCEL_ALLOWED_PATHS`), capability-style random handles, opt-in CSV injection guard.

Quick start (Docker)

# run the test suites
make test                 # = docker build --target=go-test / --target=php-test

# build FrankenPHP with the extension baked in
make build                # produces the frankenphp-easy-excel image

# or pull the published image
docker pull ghcr.io/xiidea/frankenphp8.5-easy-excel:latest

Use the shim in your app (the image ships it at /opt/easy-excel/php):

{
    "repositories": [{ "type": "path", "url": "/opt/easy-excel/php" }],
    "require": { "easy-excel/polyfill": "*" }
}

use PhpOffice\PhpSpreadsheet\Spreadsheet;          // resolved to EasyExcel\Compat\*
use PhpOffice\PhpSpreadsheet\IOFactory;

$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
$sheet->fromArray($hugeDataset);                    // batched straight into Go
$sheet->setCellValue('A1', 'Hello');                // buffered, flushed in row batches
IOFactory::createWriter($spreadsheet, 'Xlsx')->save('report.xlsx');
$spreadsheet->disconnectWorksheets();               // frees the native workbook

The aliases stay dormant when the real phpoffice/phpspreadsheet is installed or the extension is missing, so adoption can be incremental.

The shim is optional: the extension's flat easy_excel_*() ABI is usable straight from PHP with no composer dependency ? see NATIVE.md.

Configuration

| Env var | Default | Meaning | |---|---|---| | EASY_EXCEL_MAX_CONCURRENT | max(2, NumCPU) | heavy ops (open/save/scan) in flight | | EASY_EXCEL_ACQUIRE_TIMEOUT_MS | 30000 | wait before Overloaded is raised | | EASY_EXCEL_MEMORY_BUDGET_MB | 512 | estimated live-workbook bytes circuit breaker | | EASY_EXCEL_ALLOWED_PATHS | unset (any local path) | colon-separated base dirs for load/save |

Repository layout

extension/   Go module: registry, limits, exio, compat, core + easy_excel.go (bridge)
php/         Composer package: EasyExcel\Compat shim + alias bootstrap + tests
bench/       Phase-0 rig: identical workloads across 5 libraries
Dockerfile   go-test | php-test | generate | build | runner stages

Development

make test            # Docker: Go (race) + PHP suites
make host-test       # local toolchains, faster iteration
make bench           # baseline all libraries (results.csv)

Notes:

  • `extension/easy_excel.go` is excluded from gofmt: gofmt mangles `//export_php:` directives (underscores aren't recognized as directive names). `make fmt` formats only the pure packages.
  • The bridge compiles only inside the `generate`/`build` Docker stages (needs PHP ZTS headers); the five pure-Go packages build and test anywhere.
  • CI publishes `ghcr.io/<owner>/frankenphp-easy-excel` on main pushes and semver tags (see `.github/workflows/publish.yml`).

Measured performance

Write N rows × 10 mixed columns, one process per run (Docker, PHP 8.5, Apple Silicon; bench/baseline-2026-07-09-php8.5.csv). "Workload memory" is the whole-process peak RSS (VmHWM) minus the idle runtime baseline, so for easy-excel it includes the Go-side buffers that PHP's own peak-memory counter cannot see:

| Library | 100k rows | 1M rows | Workload memory (1M) | |---|---|---|---| | PhpSpreadsheet 5.8 | 23.64s | out of memory (6GB cap) | ~647MB at 100k | | rap2hpoutre/fast-excel | 6.58s | 64.49s | ~3MB | | OpenSpout 4.x | 5.85s | 60.07s | ~3MB | | fast-excel-writer 6.x | 4.29s | 45.73s | ~3MB | | easy-excel (PhpSpreadsheet API) | 1.37s | 11.91s | ~189MB | | easy-excel (native API) | 1.28s | 11.35s | ~186MB |

The two easy-excel lanes produce byte-identical files; the Compat shim costs about 5% over raw EasyExcel\Native calls. PHP-side peak memory stays at 4MB in both lanes ? the ~186MB lives in the Go extension (excelize stream buffers), which still writes 1M rows in a fraction of the memory PhpSpreadsheet needs for 100k. (The 2026-06-11 baseline ran ~1.4× faster across all lanes ? sessions vary, compare ratios, not absolute times.)

Styled report (same data + styled header, two column number formats, widths, freeze pane, auto-filter; write-styled workload, bench/baseline-2026-06-12-php8.5-phase3.csv; that session's unstyled 1M control was 11.9s, matching the table above, so its times are directly comparable):

| Library | 100k rows | 1M rows | Peak PHP memory | |---|---|---|---| | PhpSpreadsheet 5.8 | 26.79s | ? | 670MB at 100k | | easy-excel | 1.93s (13.9×) | 18.5s | 4MB |

Styles stream inline, and since Phase 3 the auto-filter no longer degrades either: the <autoFilter> element is injected into the saved container directly (COMPAT.md §16). In Phase 2 the same styled 1M lane took 121s; the streaming filter and the batch-uniform style resolver cut it to ~1.6× the unstyled write.

Status

Phase 3 (advanced compat) complete, on top of Phase 2's full style graph and worksheet structure:

  • Formulas: `getCalculatedValue()` and bulk `toArray(calculateFormulas: true)` via excelize's engine ? 466/529 PhpSpreadsheet functions, per- function table in FORMULAS.md.
  • Data validation, conditional formatting, images, sheet protection with the PhpSpreadsheet APIs; charts via a native declarative API (`addNativeChart`).
  • Streaming auto-filter: filtered million-row exports no longer degrade ? the filter is injected into the saved container.

Styles applied before their rows are written are inlined into the stream, so the usual "style header ? bulk write" report keeps constant memory and full write speed. See COMPAT.md for the precise matrix and documented divergences. Reproduce the numbers with make bench.


  Files folder image Files (156)  
File Role Description
Files folder image.claude (2 files)
Files folder image.github (1 directory)
Files folder imagebench (10 files)
Files folder imageextension (3 files, 6 directories)
Files folder imagephp (3 files, 3 directories)
Accessible without login Plain text file .dockerignore Data Auxiliary data
Accessible without login Plain text file COMPAT.md Data Auxiliary data
Accessible without login Plain text file Dockerfile Data Auxiliary data
Accessible without login Plain text file FORMULAS.md Data Auxiliary data
Accessible without login Plain text file Makefile Data Auxiliary data
Accessible without login Plain text file MISSING.md Data Auxiliary data
Accessible without login Plain text file NATIVE.md Example Example script
Accessible without login Plain text file PLAN.md Data Auxiliary data
Accessible without login Plain text file README.md Doc. Documentation

  Files folder image Files (156)  /  .claude  
File Role Description
  Accessible without login Plain text file scheduled_tasks.lock Data Auxiliary data
  Accessible without login Plain text file settings.local.json Data Auxiliary data

  Files folder image Files (156)  /  .github  
File Role Description
Files folder imageworkflows (3 files)

  Files folder image Files (156)  /  .github  /  workflows  
File Role Description
  Accessible without login Plain text file ci.yml Data Auxiliary data
  Accessible without login Plain text file publish-php.yml Data Auxiliary data
  Accessible without login Plain text file publish.yml Data Auxiliary data

  Files folder image Files (156)  /  bench  
File Role Description
  Plain text file adapters.php Class Class source
  Accessible without login Plain text file baseline-2026-06-11-php8.5.csv Data Auxiliary data
  Accessible without login Plain text file baseline-2026-06-11.csv Data Auxiliary data
  Accessible without login Plain text file baseline-2026-06-12-php8.5-phase3.csv Data Auxiliary data
  Accessible without login Plain text file baseline-2026-06-12-php8.5-styled.csv Data Auxiliary data
  Accessible without login Plain text file baseline-2026-07-09-php8.5.csv Data Auxiliary data
  Accessible without login Plain text file composer.json Data Auxiliary data
  Accessible without login Plain text file Dockerfile Data Auxiliary data
  Accessible without login Plain text file run.php Example Example script
  Accessible without login Plain text file run.sh Data Auxiliary data

  Files folder image Files (156)  /  extension  
File Role Description
Files folder imagecompat (9 files)
Files folder imagecore (19 files)
Files folder imageexio (2 files)
Files folder imagelimits (2 files)
Files folder imageregistry (2 files)
Files folder imagetools (1 directory)
  Accessible without login Plain text file easy_excel.go Data Auxiliary data
  Accessible without login Plain text file go.mod Data Auxiliary data
  Accessible without login Plain text file go.sum Data Auxiliary data

  Files folder image Files (156)  /  extension  /  compat  
File Role Description
  Accessible without login Plain text file chart.go Data Auxiliary data
  Accessible without login Plain text file conditional.go Data Auxiliary data
  Accessible without login Plain text file reverse.go Data Auxiliary data
  Accessible without login Plain text file richtext.go Data Auxiliary data
  Accessible without login Plain text file style.go Data Auxiliary data
  Accessible without login Plain text file style_test.go Data Auxiliary data
  Accessible without login Plain text file validation.go Data Auxiliary data
  Accessible without login Plain text file values.go Data Auxiliary data
  Accessible without login Plain text file values_test.go Data Auxiliary data

  Files folder image Files (156)  /  extension  /  core  
File Role Description
  Accessible without login Plain text file csv.go Data Auxiliary data
  Accessible without login Plain text file customprop_test.go Data Auxiliary data
  Accessible without login Plain text file filterpatch.go Data Auxiliary data
  Accessible without login Plain text file phase3.go Data Auxiliary data
  Accessible without login Plain text file phase3_test.go Data Auxiliary data
  Accessible without login Plain text file phase4.go Data Auxiliary data
  Accessible without login Plain text file phase42.go Data Auxiliary data
  Accessible without login Plain text file phase42_test.go Data Auxiliary data
  Accessible without login Plain text file phase43.go Data Auxiliary data
  Accessible without login Plain text file phase43_test.go Data Auxiliary data
  Accessible without login Plain text file phase44.go Data Auxiliary data
  Accessible without login Plain text file phase44_test.go Data Auxiliary data
  Accessible without login Plain text file phase4_test.go Data Auxiliary data
  Accessible without login Plain text file structure.go Data Auxiliary data
  Accessible without login Plain text file structure_test.go Data Auxiliary data
  Accessible without login Plain text file styles.go Data Auxiliary data
  Accessible without login Plain text file workbook.go Data Auxiliary data
  Accessible without login Plain text file workbook_extra_save_test.go Data Auxiliary data
  Accessible without login Plain text file workbook_test.go Data Auxiliary data

  Files folder image Files (156)  /  extension  /  exio  
File Role Description
  Accessible without login Plain text file paths.go Data Auxiliary data
  Accessible without login Plain text file paths_test.go Data Auxiliary data

  Files folder image Files (156)  /  extension  /  limits  
File Role Description
  Accessible without login Plain text file limits.go Data Auxiliary data
  Accessible without login Plain text file limits_test.go Data Auxiliary data

  Files folder image Files (156)  /  extension  /  registry  
File Role Description
  Accessible without login Plain text file registry.go Data Auxiliary data
  Accessible without login Plain text file registry_test.go Data Auxiliary data

  Files folder image Files (156)  /  extension  /  tools  
File Role Description
Files folder imageformula-coverage (2 files)

  Files folder image Files (156)  /  extension  /  tools  /  formula-coverage  
File Role Description
  Accessible without login Plain text file main.go Data Auxiliary data
  Accessible without login Plain text file phpspreadsheet-functions.txt Doc. Documentation

  Files folder image Files (156)  /  php  
File Role Description
Files folder imagesrc (2 files, 1 directory)
Files folder imagetests (2 files, 2 directories)
Files folder imagetools (1 file)
  Accessible without login Plain text file .compat-surface.json Data Auxiliary data
  Accessible without login Plain text file composer.json Data Auxiliary data
  Accessible without login Plain text file README.md Doc. Documentation

  Files folder image Files (156)  /  php  /  src  
File Role Description
Files folder imageEasyExcel (2 files, 2 directories)
  Accessible without login Plain text file aliasing.php Example Example script
  Accessible without login Plain text file bootstrap.php Aux. Configuration script

  Files folder image Files (156)  /  php  /  src  /  EasyExcel  
File Role Description
Files folder imageCompat (5 files, 10 directories)
Files folder imageException (4 files)
  Plain text file Native.php Class Class source
  Plain text file UnsupportedApiException.php Class Class source

  Files folder image Files (156)  /  php  /  src  /  EasyExcel  /  Compat  
File Role Description
Files folder imageCalculation (1 file)
Files folder imageCell (8 files)
Files folder imageChart (6 files)
Files folder imageDocument (1 file)
Files folder imageReader (3 files)
Files folder imageRichText (2 files)
Files folder imageShared (2 files)
Files folder imageStyle (10 files)
Files folder imageWorksheet (17 files, 1 directory)
Files folder imageWriter (5 files)
  Plain text file Comment.php Class Class source
  Plain text file Exception.php Class Class source
  Plain text file IOFactory.php Class Class source
  Plain text file NamedRange.php Class Class source
  Plain text file Spreadsheet.php Class Class source

  Files folder image Files (156)  /  php  /  src  /  EasyExcel  /  Compat  /  Calculation  
File Role Description
  Plain text file Calculation.php Class Class source

  Files folder image Files (156)  /  php  /  src  /  EasyExcel  /  Compat  /  Cell  
File Role Description
  Plain text file Cell.php Class Class source
  Plain text file Coordinate.php Class Class source
  Plain text file DataType.php Class Class source
  Plain text file DataValidation.php Class Class source
  Plain text file DefaultValueBinder.php Class Class source
  Plain text file Hyperlink.php Class Class source
  Plain text file IValueBinder.php Class Class source
  Plain text file StringValueBinder.php Class Class source

  Files folder image Files (156)  /  php  /  src  /  EasyExcel  /  Compat  /  Chart  
File Role Description
  Plain text file Chart.php Class Class source
  Plain text file DataSeries.php Class Class source
  Plain text file DataSeriesValues.php Class Class source
  Plain text file Legend.php Class Class source
  Plain text file PlotArea.php Class Class source
  Plain text file Title.php Class Class source

  Files folder image Files (156)  /  php  /  src  /  EasyExcel  /  Compat  /  Document  
File Role Description
  Plain text file Properties.php Class Class source

  Files folder image Files (156)  /  php  /  src  /  EasyExcel  /  Compat  /  Reader  
File Role Description
  Plain text file Csv.php Class Class source
  Plain text file IReadFilter.php Class Class source
  Plain text file Xlsx.php Class Class source

  Files folder image Files (156)  /  php  /  src  /  EasyExcel  /  Compat  /  RichText  
File Role Description
  Plain text file RichText.php Class Class source
  Plain text file Run.php Class Class source

  Files folder image Files (156)  /  php  /  src  /  EasyExcel  /  Compat  /  Shared  
File Role Description
  Plain text file Date.php Class Class source
  Plain text file StreamPath.php Class Class source

  Files folder image Files (156)  /  php  /  src  /  EasyExcel  /  Compat  /  Style  
File Role Description
  Plain text file Alignment.php Class Class source
  Plain text file Border.php Class Class source
  Plain text file Borders.php Class Class source
  Plain text file Color.php Class Class source
  Plain text file Conditional.php Class Class source
  Plain text file Fill.php Class Class source
  Plain text file Font.php Class Class source
  Plain text file NumberFormat.php Class Class source
  Plain text file Protection.php Class Class source
  Plain text file Style.php Class Class source

  Files folder image Files (156)  /  php  /  src  /  EasyExcel  /  Compat  /  Worksheet  
File Role Description
Files folder imageAutoFilter (1 file, 1 directory)
  Plain text file AutoFilter.php Class Class source
  Plain text file Column.php Class Class source
  Plain text file ColumnCellIterator.php Class Class source
  Plain text file ColumnDimension.php Class Class source
  Plain text file ColumnIterator.php Class Class source
  Plain text file Drawing.php Class Class source
  Plain text file HeaderFooter.php Class Class source
  Plain text file MemoryDrawing.php Class Class source
  Plain text file PageMargins.php Class Class source
  Plain text file PageSetup.php Class Class source
  Plain text file Protection.php Class Class source
  Plain text file Row.php Class Class source
  Plain text file RowCellIterator.php Class Class source
  Plain text file RowDimension.php Class Class source
  Plain text file RowIterator.php Class Class source
  Plain text file SheetView.php Class Class source
  Plain text file Worksheet.php Class Class source

  Files folder image Files (156)  /  php  /  src  /  EasyExcel  /  Compat  /  Worksheet  /  AutoFilter  
File Role Description
Files folder imageColumn (1 file)
  Plain text file Column.php Class Class source

  Files folder image Files (156)  /  php  /  src  /  EasyExcel  /  Compat  /  Worksheet  /  AutoFilter  /  Column  
File Role Description
  Plain text file Rule.php Class Class source

  Files folder image Files (156)  /  php  /  src  /  EasyExcel  /  Compat  /  Writer  
File Role Description
  Plain text file BaseWriter.php Class Class source
  Plain text file Csv.php Class Class source
  Plain text file Html.php Class Class source
  Plain text file IWriter.php Class Class source
  Plain text file Xlsx.php Class Class source

  Files folder image Files (156)  /  php  /  src  /  EasyExcel  /  Exception  
File Role Description
  Plain text file BadHandle.php Class Class source
  Plain text file EasyExcelException.php Class Class source
  Plain text file Overloaded.php Class Class source
  Plain text file PathDenied.php Class Class source

  Files folder image Files (156)  /  php  /  tests  
File Role Description
Files folder imagecases (16 files)
Files folder imageFake (1 file)
  Plain text file run.php Class Class source
  Plain text file smoke.php Class Class source

  Files folder image Files (156)  /  php  /  tests  /  cases  
File Role Description
  Plain text file aliasing.php Class Class source
  Plain text file coordinate.php Class Class source
  Accessible without login Plain text file date.php Example Example script
  Accessible without login Plain text file default_dimensions.php Example Example script
  Accessible without login Plain text file eager_aliasing.php Example Example script
  Plain text file io.php Class Class source
  Accessible without login Plain text file phase3.php Example Example script
  Accessible without login Plain text file save_staging.php Example Example script
  Plain text file spreadsheet.php Class Class source
  Plain text file string-value-binder.php Class Class source
  Accessible without login Plain text file styles.php Example Example script
  Plain text file wave41.php Class Class source
  Plain text file wave42.php Class Class source
  Accessible without login Plain text file wave43.php Example Example script
  Accessible without login Plain text file wave44.php Example Example script
  Plain text file wave45.php Class Class source

  Files folder image Files (156)  /  php  /  tests  /  Fake  
File Role Description
  Plain text file functions.php Class Class source

  Files folder image Files (156)  /  php  /  tools  
File Role Description
  Accessible without login Plain text file compat-surface-diff.php Example Example script

The PHP Classes site has supported package installation using the Composer tool since 2013, as you may verify by reading this instructions page.
Install with Composer Install with Composer
 Version Control Unique User Downloads  
 100%
Total:0
This week:0