PHPackages                             kolay/xlsx-stream - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [File &amp; Storage](/categories/file-storage)
4. /
5. kolay/xlsx-stream

ActiveLibrary[File &amp; Storage](/categories/file-storage)

kolay/xlsx-stream
=================

High-performance XLSX streaming writer for Laravel with zero disk I/O and direct S3 support

v1.0.2(7mo ago)383.0k—1.7%1[2 issues](https://github.com/turgutahmet/kolay-xlsx-stream/issues)MITPHPPHP ^8.0

Since Sep 7Pushed 7mo ago2 watchersCompare

[ Source](https://github.com/turgutahmet/kolay-xlsx-stream)[ Packagist](https://packagist.org/packages/kolay/xlsx-stream)[ Docs](https://github.com/turgutahmet/kolay-xlsx-stream)[ RSS](/packages/kolay-xlsx-stream/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (1)Dependencies (5)Versions (4)Used By (0)

Kolay XLSX Stream
=================

[](#kolay-xlsx-stream)

[![Latest Version on Packagist](https://camo.githubusercontent.com/2bfbd3a532c298ec3c65aa20cb42dd38305e7a193d39207a33521aa58a896230/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6b6f6c61792f786c73782d73747265616d2e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/kolay/xlsx-stream)[![Total Downloads](https://camo.githubusercontent.com/a422ffb96f6ac6c2d04f515f62d6421609892a96d050bc24a6544c83398b53aa/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f6b6f6c61792f786c73782d73747265616d2e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/kolay/xlsx-stream)[![License](https://camo.githubusercontent.com/23855a715c9b625b916f560f3ccbb3b7b2311d5dc8d119d583180f8b66c375c6/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f6b6f6c61792f786c73782d73747265616d2e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/kolay/xlsx-stream)[![PHP Version](https://camo.githubusercontent.com/d92901701ad2a8845384b083375dd5ccec5017a2aa7b0f177416092f6f7787e8/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f6b6f6c61792f786c73782d73747265616d2e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/kolay/xlsx-stream)

High-performance XLSX streaming writer for Laravel with **zero disk I/O** and **direct S3 support**. Perfect for exporting millions of rows without memory issues.

Why This Package?
-----------------

[](#why-this-package)

### The Problem with Existing Solutions

[](#the-problem-with-existing-solutions)

Most PHP Excel libraries (PHPSpreadsheet, Spout, Laravel Excel) have critical limitations:

- **Memory Issues**: Load entire documents in RAM (unusable for large files)
- **Disk I/O**: Write temporary files then upload to S3 (2x I/O, slow)
- **No True Streaming**: Can't stream directly to S3

### Our Solution

[](#our-solution)

- **Zero Disk I/O**: Direct streaming to S3 using multipart upload
- **Constant Memory**: O(1) memory usage - only 32MB buffer regardless of file size
- **Blazing Fast**: 2-3x faster than alternatives
- **Production Tested**: Successfully exported 4.65 million rows (500MB+ files)

Performance Comparison
----------------------

[](#performance-comparison)

### Comprehensive Benchmark Results (September 2025)

[](#comprehensive-benchmark-results-september-2025)

RowsLocal SpeedLocal MemoryLocal TimeS3 SpeedS3 MemoryS3 TimeFile Size10047,913 rows/s2 MB0.00s99 rows/s0 MB1.01s0.01 MB500161,183 rows/s0 MB0.00s362 rows/s0 MB1.38s0.02 MB1,000161,711 rows/s0 MB0.01s913 rows/s0 MB1.09s0.04 MB5,000167,101 rows/s0 MB0.03s3,092 rows/s0 MB1.62s0.2 MB10,000183,281 rows/s0 MB0.05s5,411 rows/s0 MB1.85s0.4 MB25,000187,322 rows/s0 MB0.13s11,482 rows/s0 MB2.18s1 MB50,000187,455 rows/s2 MB0.27s5,829 rows/s2 MB8.58s2 MB100,000182,167 rows/s0 MB0.55s9,288 rows/s4 MB10.77s4 MB250,000185,586 rows/s0 MB1.35s59,744 rows/s12 MB (±6)4.18s10 MB500,000184,268 rows/s0 MB2.71s28,553 rows/s20 MB (±18)17.51s20 MB750,000182,648 rows/s0 MB4.11s33,504 rows/s30 MB (±26)22.39s30 MB1,000,000182,693 rows/s0 MB5.47s43,215 rows/s40 MB (±38)23.14s40 MB1,500,000180,578 rows/s0 MB8.31s36,733 rows/s60 MB (±58)40.84s60 MB2,000,000177,012 rows/s0 MB11.30s51,323 rows/s79 MB (±77)38.97s79 MB3,000,000---39,150 rows/s117 MB (±117)76.63s119 MB4,000,000---42,500 rows/s160 MB (±156)94.12s158 MB4,500,000---46,462 rows/s178 MB (±178)96.85s178 MB*Note: Tests with 1M+ rows automatically create multiple sheets (Excel limit: 1,048,576 rows per sheet)*
*Note: ± values in S3 Memory column indicate memory fluctuation during streaming due to periodic part uploads*

### Understanding Memory Behavior

[](#understanding-memory-behavior)

#### Local File System

[](#local-file-system)

- **True O(1) Memory**: Constant memory usage regardless of file size
- **No Growth**: Memory stays at 0-2MB even for millions of rows
- **Speed**: 180,000+ rows/second consistently

#### S3 Streaming Memory Fluctuation

[](#s3-streaming-memory-fluctuation)

The ± values in S3 memory represent **normal memory fluctuation** during streaming:

1. **Buffer Accumulation Phase** (↑ Memory Growth)

    - Data is compressed and buffered until reaching 32MB
    - Memory grows gradually as buffer fills
2. **Part Upload Phase** (↓ Memory Drop)

    - When buffer reaches 32MB, it's uploaded to S3
    - After upload, memory drops back to baseline
    - This creates the characteristic sawtooth pattern
3. **Example: 1M Rows Test**

    - Average memory: 40MB
    - Fluctuation: ±38MB
    - Pattern: Memory oscillates between ~2MB (after upload) and ~78MB (before upload)
    - This is **completely normal** and expected behavior

### Performance Highlights

[](#performance-highlights)

- **Local File System**: ~180,000 rows/second with true O(1) memory
- **S3 Streaming**: 30,000-50,000 rows/second with periodic memory fluctuation
- **Memory Efficiency**: Local uses &lt;2MB, S3 averages 40MB per million rows
- **Multi-sheet Support**: Automatic sheet creation at Excel's 1,048,576 row limit
- **Production Ready**: Successfully tested with 4.5 million rows

### Comparison with Other Libraries

[](#comparison-with-other-libraries)

Package1M Rows TimeMemory UsageDisk UsageS3 SupportPHPSpreadsheet❌ Crashes~8GBFull fileIndirectSpout~60 sec~100MB+Full fileIndirectLaravel Excel~90 sec~500MB+Full fileIndirect**Kolay XLSX Stream (Local)**✅ **5.5 sec**✅ **0 MB**✅ **Zero**N/A**Kolay XLSX Stream (S3)**✅ **23 sec**✅ **40MB avg**✅ **Zero**✅ **Direct**Requirements
------------

[](#requirements)

- PHP 8.0+
- Laravel 9.0+ (supports Laravel 9, 10, 11 &amp; 12)
- AWS SDK (only if using S3 streaming)

Installation
------------

[](#installation)

```
composer require kolay/xlsx-stream
```

### Publish Configuration (Optional)

[](#publish-configuration-optional)

```
php artisan vendor:publish --tag=xlsx-stream-config
```

Quick Start
-----------

[](#quick-start)

### Basic Usage - Local File

[](#basic-usage---local-file)

```
use Kolay\XlsxStream\Writers\SinkableXlsxWriter;
use Kolay\XlsxStream\Sinks\FileSink;

// Create writer with file sink
$sink = new FileSink('/path/to/output.xlsx');
$writer = new SinkableXlsxWriter($sink);

// Set headers
$writer->startFile(['Name', 'Email', 'Phone']);

// Write rows
$writer->writeRow(['John Doe', 'john@example.com', '+1234567890']);
$writer->writeRow(['Jane Smith', 'jane@example.com', '+0987654321']);

// Or write multiple rows at once
$writer->writeRows([
    ['Bob Johnson', 'bob@example.com', '+1111111111'],
    ['Alice Brown', 'alice@example.com', '+2222222222'],
]);

// Finish and close file
$stats = $writer->finishFile();

echo "Generated {$stats['rows']} rows in {$stats['sheets']} sheet(s)";
```

### Direct S3 Streaming (Zero Disk I/O)

[](#direct-s3-streaming-zero-disk-io)

```
use Kolay\XlsxStream\Writers\SinkableXlsxWriter;
use Kolay\XlsxStream\Sinks\S3MultipartSink;
use Aws\S3\S3Client;

// Create S3 client
$s3Client = new S3Client([
    'region' => 'us-east-1',
    'version' => 'latest',
    'credentials' => [
        'key' => env('AWS_ACCESS_KEY_ID'),
        'secret' => env('AWS_SECRET_ACCESS_KEY'),
    ],
]);

// Create S3 sink with 32MB parts
$sink = new S3MultipartSink(
    $s3Client,
    'my-bucket',
    'exports/report.xlsx',
    32 * 1024 * 1024 // 32MB parts for optimal performance
);

$writer = new SinkableXlsxWriter($sink);

// Configure for maximum performance
$writer->setCompressionLevel(1)      // Fastest compression
       ->setBufferFlushInterval(10000); // Flush every 10K rows

$writer->startFile(['ID', 'Name', 'Email', 'Status']);

// Stream millions of rows with constant 32MB memory
User::query()
    ->select(['id', 'name', 'email', 'status'])
    ->chunkById(1000, function ($users) use ($writer) {
        foreach ($users as $user) {
            $writer->writeRow([
                $user->id,
                $user->name,
                $user->email,
                $user->status
            ]);
        }
    });

$stats = $writer->finishFile();
```

### Laravel Job Example

[](#laravel-job-example)

```
