PHPackages                             lekoala/spread-compat - 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. [PDF &amp; Document Generation](/categories/documents)
4. /
5. lekoala/spread-compat

ActiveLibrary[PDF &amp; Document Generation](/categories/documents)

lekoala/spread-compat
=====================

Easily manipulate PhpSpreadsheet, OpenSpout and League CSV

0.10.1(2mo ago)1216.3k↓34.3%2[1 PRs](https://github.com/lekoala/spread-compat/pulls)1MITPHPPHP ^8.1.2CI passing

Since Dec 20Pushed 1mo ago2 watchersCompare

[ Source](https://github.com/lekoala/spread-compat)[ Packagist](https://packagist.org/packages/lekoala/spread-compat)[ GitHub Sponsors](https://github.com/lekoala)[ RSS](/packages/lekoala-spread-compat/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (10)Dependencies (19)Versions (35)Used By (1)

Spread Compat
=============

[](#spread-compat)

> Easily manipulate PhpSpreadsheet, OpenSpout, League CSV and Baresheet

Why use this ?
--------------

[](#why-use-this-)

Importing/exporting csv data is a very common task in web development. While it's a very efficient format, it's also somewhat difficult for end users that are used to Excel. This is why you often end up accepting also xlsx or ods format as a import/export target.

Ideally, importing single sheets of csv, excel or ods should be just a matter of changing an adapter. Thankfully, this package does just this :-)

Supported packages
------------------

[](#supported-packages)

Baresheet (Native): very fast csv, xlsx and ods import/export, but limited features. Can read/output streams. It is used as our default native adapter.

OpenSpout: fast csv, excel (xlsx) and ods import/export

League CSV: very fast csv import/export. Can read streams.

PhpSpreadsheet: slow excel (xls, xlsx) and ods and csv import/export, but more features

SimpleXLSX: very fast excel import/export

This package will prioritize installed library, by order of performance. You can also pick your preferred default adapter for each format like this:

```
SpreadCompat::$preferredCsvAdapter = SpreadCompat::BARESHEET; // or SpreadCompat::NATIVE
SpreadCompat::$preferredXlsxAdapter = SpreadCompat::BARESHEET;
SpreadCompat::$preferredOdsAdapter = SpreadCompat::BARESHEET;
```

Using the facade
----------------

[](#using-the-facade)

While you can use individual adapters, it's very likely you don't want to bother too much how your files are read and written. This package provides a simple facade with static methods in order to read and write files.

Please note that read methods return a `Generator`. If you want an array, you need to use `iterator_to_array`.

```
$data = iterator_to_array(SpreadCompat::read('myfile.csv'));

// or
foreach(SpreadCompat::read('myfile.xlsx') as $row) {
    // Do something
}

// or even
foreach(SpreadCompat::read('myfile.ods') as $row) {
    // Do something
}
```

Output to browser
-----------------

[](#output-to-browser)

This package includes a simple way to leverage output to browser type of functionnality.

Some adapters allow you to stream directly the response.

```
SpreadCompat::output('myfile.csv');
exit();
```

Configure
---------

[](#configure)

### Using named arguments

[](#using-named-arguments)

This package accepts options using ...opts, this means you can freely use named arguments or pass an array.

```
$data = iterator_to_array(SpreadCompat::read('myfile.csv', assoc: true));

// or
$data = iterator_to_array(SpreadCompat::read('myfile.csv', ...$opts));
```

### Using options object

[](#using-options-object)

You can also use the `Options` class that regroups all available options for all adapters. Unsupported options are ignored.

```
$options = new Options();
$options->separator = ";";
$data = iterator_to_array(SpreadCompat::read('myfile.csv', $options));
```

Setting the adapter
-------------------

[](#setting-the-adapter)

Instead of relying on the static variables, you can choose which adapter to use:

```
$csvData = SpreadCompat::readString($csv, adapter: SpreadCompat::BARESHEET);
// or
$options = new Options();
$options->adapter = SpreadCompat::NATIVE;
$csvData = SpreadCompat::readString($csv, $options);
```

Security
--------

[](#security)

### CSV Formula Injection

[](#csv-formula-injection)

When exporting to CSV, cell values starting with `=`, `+`, `-`, `@`, `\t`, or `\r` can be interpreted as formulas by spreadsheet software like Excel. This is known as [CSV Formula Injection](https://owasp.org/www-community/attacks/CSV_Injection).

By default, this library does NOT escape these characters to ensure that the data is not altered and remains compatible with other tools that may expect raw data.

If you are generating CSV files for end users to open in Excel and want to protect them from potential formula injection, you should enable the `escapeFormulas` option:

```
SpreadCompat::write('myfile.csv', $data, escapeFormulas: true);
```

This will prepend a single quote (`'`) to any cell value that could be interpreted as a formula.

Worksheets
----------

[](#worksheets)

This package supports only 1 worksheet, as it is meant to be able to replace csv by xlsx or vice versa

Benchmarks
----------

[](#benchmarks)

Since we can compare our solutions, there is a built in bench script. You can check the results here

- [read benchmark](docs/bench-read.md)
- [write benchmark](docs/bench-write.md)

For simple imports/exports, it's very clear that using the `Native` (Baresheet) adapter is the fastest overall choice.

Stop wasting cpu cycles right now and please use the most efficient adapter :-)

###  Health Score

50

—

FairBetter than 96% of packages

Maintenance88

Actively maintained with recent releases

Popularity35

Limited adoption so far

Community14

Small or concentrated contributor base

Maturity52

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 99.2% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~27 days

Recently: every ~63 days

Total

31

Last Release

74d ago

PHP version history (2 changes)0.1.0PHP ^8.1

0.10.0PHP ^8.1.2

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/250762?v=4)[Thomas Portelange](/maintainers/lekoala)[@lekoala](https://github.com/lekoala)

---

Top Contributors

[![lekoala](https://avatars.githubusercontent.com/u/250762?v=4)](https://github.com/lekoala "lekoala (120 commits)")[![nyamsprod](https://avatars.githubusercontent.com/u/51073?v=4)](https://github.com/nyamsprod "nyamsprod (1 commits)")

---

Tags

csvexcelgeneratorphpspreadsheetstreamphppackageexcelxlsxlsxcsvspreadsheet

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP\_CodeSniffer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/lekoala-spread-compat/health.svg)

```
[![Health](https://phpackages.com/badges/lekoala-spread-compat/health.svg)](https://phpackages.com/packages/lekoala-spread-compat)
```

###  Alternatives

[openspout/openspout

PHP Library to read and write spreadsheet files (CSV, XLSX and ODS), in a fast and scalable way

1.2k57.6M131](/packages/openspout-openspout)[seine/seine

Seine - Write spreadsheets of various formats to a stream

1270.3k](/packages/seine-seine)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
