PHPackages                             saschakliche/phpxlsxreader - 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. saschakliche/phpxlsxreader

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

saschakliche/phpxlsxreader
==========================

A very simple library for reading Office Open XML (OOXML) spreadsheet files (XLSX)

v1.3.0(1mo ago)07MITPHPPHP ^8.3

Since Apr 13Pushed 1mo agoCompare

[ Source](https://github.com/SaschaKliche/PhpXlsxReader)[ Packagist](https://packagist.org/packages/saschakliche/phpxlsxreader)[ RSS](/packages/saschakliche-phpxlsxreader/feed)WikiDiscussions master Synced 1w ago

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

XlsxReader
==========

[](#xlsxreader)

This library provides a simple interface to read Office Open XML (OOXML) spreadsheet files (XLSX).

Main features
-------------

[](#main-features)

- Read the whole file into an [array](#readasarray-reading-a-workbook-into-an-array)or read a file [row by row](#read-reading-a-workbook-using-generators)to reduce memory consumption
- Read a file containing header rows into an [associative array](#readwithheader-reading-a-workbook-with-header-row-as-an-associative-array)(think CSV)
- Read only specific [worksheets](#worksheets-selecting-the-worksheets-to-load-from-a-workbook), [rows](#rows-selecting-the-rows-to-load-from-the-worksheets), [columns](#columns-selecting-the-columns-to-load-from-the-worksheets)
- [Include](#includemissingrows-include-missing-rows)or [skip](#skipmissingrows-ignore-missing-rows)missing row
- [Include](#includemissingcells-include-missing-cells)or [skip](#skipmissingcells-ignore-missing-cells)missing columns
- Read only the cell values or additional information like raw values, formulas, hyperlinks, and format strings by using [`Cell` objects](#returncellobjects-return-cell-object-instances-instead-of-cell-values)
- Cell values are returned as string, integer, float, or DateTime by default, based on the cell contents
- Use [custom formatter closures](#customformats-apply-custom-formatting)
- Use [cell addresses](#usecelladdress-indexing-cells-by-cell-address)(e.g. E17) or [column indexes](#usecolumnindex-indexing-cells-by-column-index-number)(e.g. 5)
- Retrieve [metadata](#getmetadata-retrieve-workbook-metadata) without reading the whole file
- Retrieve [worksheet names](#getworksheetnames-retrieve-the-worksheet-names-of-a-workbook) without reading the whole file
- [Configuration](#configuration) via array or fluent helper methods

Note

The library is not optimized to handle large files. It might use excessive memory and CPU time. See [performance considerations](#performance-considerations) for further information.

Important

The library is not hardened against malformed files, this could create security issues.

License
-------

[](#license)

This library is licensed under the [MIT license](https://opensource.org/license/mit). See the `LICENSE` file for details.

Requirements
------------

[](#requirements)

The library requires at least PHP 8.3 with the following extensions:

- ctype
- xmlreader
- zip

PHP 8.3, PHP 8.4, and PHP 8.5 are supported.

Installation via Composer
-------------------------

[](#installation-via-composer)

Installation is quick &amp; easy with [Composer](https://getcomposer.org/):

```
composer require saschakliche/phpxlsxreader
```

Overview
--------

[](#overview)

By default, the library reads all worksheets in a given file but that can be configured. For each available row each available cell will be read. Available means that the row/cell does exist in the input file. Rows or cells that do not exist in the input file will not be returned at all. That means that the data returned can contain non-consecutive rows/cells.

The main class is `XlsxReader`:

```
use SaschaKliche\PhpXlsxReader\XlsxReader;

$reader = new XlsxReader();
$reader->open();

foreach ($reader->read() as $worksheetName => $rows) {
    print 'Worksheet ' . $worksheetName . PHP_EOL;
    foreach ($rows as $rowIndex => $row) {
        print "\t" . 'Row ' . $rowIndex . PHP_EOL;
        foreach ($row as $columnAddress => $column) {
            // $column can be int/float/string/DateTime unless a custom formatter is used
            print "\t\t" . 'Cell ' . $columnAddress . ': ' . ($column instanceof DateTime ? $column->format('Y-m-d H:i:s') : $column) . "\n";
        }
    }
}
```

`XlsxReader` API
----------------

[](#xlsxreader-api)

The following methods are provided by `XlsxReader`:

```
// opening a file
open(string $filePath): XlsxReader

// reading the actual data
read(): Generator
readAsArray(): array
readWithHeader(int|array $headerRowIndex = 0): array

// retrieving information about the workbook
getHeaders(int|string $worksheet = ''): array
getMetadata(): Metadata
getWorksheetName(): string
getWorksheetNames(): array
```

Additionally, the `XlsxReader` instance provides methods for [configuration](#configuration)and to [retrieve performance information](#performance-considerations).

### `read()`: Reading a workbook using generators

[](#read-reading-a-workbook-using-generators)

Reads a workbook by returning generators that allow to walk through a workbook without having to hold it entirely in memory, effectively iterating through the workbook row by row.

This uses less memory on larger files than [`XlsxReader::readAsArray()`](#readasarray-reading-a-workbook-into-an-array)and [`XlsxReader::readWithHeader()`](#readwithheader-reading-a-workbook-with-header-row-as-an-associative-array). A larger file in this sense doesn't necessarily mean that the XLSX file size is larger. It depends on other factors, especially the actual number of cells used, the amount and length of different strings used.

Syntax:

```
XlsxReader::read(): Generator
```

Example:

```
use SaschaKliche\PhpXlsxReader\XlsxReader;

$reader = new XlsxReader();
$reader->open();

foreach ($reader->read() as $worksheetName => $rows) {
    print $worksheetName . PHP_EOL;
    foreach ($rows as $rowIndex => $row) {
        print "\t" . $rowIndex . PHP_EOL;
        foreach ($row as $columnAddress => $column) {
            print "\t\t" . $columnAddress . ': ' . ($column instanceof DateTime ? $column->format('Y-m-d H:i:s') : $column) . "\n";
        }
    }
}
```

### `readAsArray()`: Reading a workbook into an array

[](#readasarray-reading-a-workbook-into-an-array)

Reads a workbook entirely and returns the contents as an array. The array contains an entry for each worksheet.

Each worksheet contains an array for each row, indexed by the row number (1-based).

Each row contains an array with the row's columns, indexed by either the cell address (default) or the column index. This can be controlled using the option `Configuration::USE_CELL_ADDRESS`.

This will use more memory on larger files than [`XlsxReader::read()`](#read-reading-a-workbook-using-generators)but might be easier to work with.

Syntax:

```
XlsxReader::readAsArray(): array
```

Example:

```
use SaschaKliche\PhpXlsxReader\XlsxReader;

$reader = new XlsxReader();
$reader->open();

// using cell address notation
$data = $reader->useCellAddress()->readAsArray();
// $data[][][]

// using 1-based column index notation
$data = $reader->useColumnIndex()->readAsArray();
// $data[][][]

// reading just a single worksheet's data
$sheet1 = $reader->worksheets(['sheet1'])->readAsArray();
// $data['sheet1'][][]
```

### `readWithHeader()`: Reading a workbook with header row as an associative array

[](#readwithheader-reading-a-workbook-with-header-row-as-an-associative-array)

By default, the first available row of each worksheet is treated as containing headers. Alternatively, the row that should be used as a header row can be specified as a parameter, either globally or per worksheet.

The header row itself will not be returned. The headers itself can be retrieved afterwards with [`getHeaders()`](#getheaders-retrieve-headers).

Each returned row will be an associative array where columns are not indexed by the cell address (e.g. `A3`) but by the value of the header row's column instead.

This will use more memory on larger files than [`XlsxReader::read()`](#read-reading-a-workbook-using-generators)but might be easier to work with.

Syntax:

```
XlsxReader::readWithHeader(int|array $headerRowIndex = 0): array
```

Use first available row as header for all worksheets:

```
use SaschaKliche\PhpXlsxReader\XlsxReader;

$reader = new XlsxReader();

$data = $reader
    ->open()
    ->readWithHeader();

// $data[][][]
```

Use third row as header for all worksheets:

```
use SaschaKliche\PhpXlsxReader\XlsxReader;

$reader = new XlsxReader();

$data = $reader
    ->open()
    ->readWithHeader(3);

// $data[][][]
```

Use different header rows per worksheet:

```
use SaschaKliche\PhpXlsxReader\XlsxReader;

$reader = new XlsxReader();

$data = $reader
    ->open()
    ->readWithHeader(['Sheet1' => 1, 'Sheet2' => 3]);
    // other existing worksheets will use the first available row as header

// $data[][][]
```

The default for `$headerRowIndex` is `0`, i.e. the first available row is used as header.

`includeMissingCells()` can be used to make sure a cell is returned for each header for each row even if a cell for that header does not exist in a row in the input file.

```
use SaschaKliche\PhpXlsxReader\XlsxReader;

$reader = new XlsxReader();

$data = $reader
    ->open()
    ->includeMissingCells()
    ->readWithHeader();

// $data[][][]
```

#### `getHeaders()`: Retrieve headers

[](#getheaders-retrieve-headers)

To retrieve the headers after reading the file, use `getHeaders()`:

Syntax:

```
XlsxReader::getHeaders(int|string $worksheet = ''): array
```

Example:

```
use SaschaKliche\PhpXlsxReader\XlsxReader;

$reader = new XlsxReader();
$reader->open()->readWithHeader();

// headers for all worksheets
$headers = $reader->getHeaders();
// $headers[][] = []

// headers for a specific worksheet identified by the worksheet name
$headersSheet1 = $reader->getHeaders('Sheet1');
// $headersSheet1[] = []

// headers for a specific worksheet identified by the index number
$headersSheet1 = $reader->getHeaders(3);
// $headersSheet1[] = []
```

### `getWorksheetNames()`: Retrieve the worksheet names of a workbook

[](#getworksheetnames-retrieve-the-worksheet-names-of-a-workbook)

The names of the worksheets present in a workbook can be retrieved using `XlsxReader::getWorksheetNames()`.

```
use SaschaKliche\PhpXlsxReader\XlsxReader;

$reader = new XlsxReader();

$worksheetNames = $reader
    ->open()
    ->getWorksheetNames();

// e.g. ['sheet1', 'sheet2', 'sheet3']
```

### `getWorksheetName()`: Retrieve the name of a single worksheet

[](#getworksheetname-retrieve-the-name-of-a-single-worksheet)

The names of the worksheets present in a workbook can be retrieved using `XlsxReader::getWorksheetName(int $worksheetIndex)`.

```
use SaschaKliche\PhpXlsxReader\XlsxReader;

$reader = new XlsxReader();

$worksheetName = $reader
    ->open()
    ->getWorksheetName(2);

// e.g. 'sheet2'
```

### `getMetadata()`: Retrieve workbook metadata

[](#getmetadata-retrieve-workbook-metadata)

```
use SaschaKliche\PhpXlsxReader\Model\Metadata;
use SaschaKliche\PhpXlsxReader\XlsxReader;

$reader = new XlsxReader();

$metadata = $reader
    ->open()
    ->getMetadata();                    // Metadata instance

$metadata->has();        // bool
$metadata->get();        // string|null
```

The available metadata properties are:

```
Metadata::CREATED            // date/time when the file was created
Metadata::CREATOR            // name of the person who created the file
Metadata::LAST_MODIFIED_BY   // date/time when the file was last modified
Metadata::MODIFIED           // name of the person who last modified the file
```

`CREATOR` and `MODIFIED` are date/time strings in the form, `Y-m-d\\TH:i:sp`, e.g. `2026-03-24T17:17:24Z`.

Configuration
-------------

[](#configuration)

The library provides several options to configure. These options can be set when instantiating the `XlsxReader` class ...

```
use SaschaKliche\PhpXlsxReader\Configuration;
use SaschaKliche\PhpXlsxReader\XlsxReader;

// default configuration
$configuration = [
    Configuration::COLUMNS_TO_LOAD => [],
    Configuration::CUSTOM_FORMATS => [],
    Configuration::RETURN_CELL_OBJECTS => false,
    Configuration::READ_FORMULAS => false, // only if Configuration::RETURN_CELL_OBJECTS set to true
    Configuration::READ_HYPERLINKS => false, // only if Configuration::RETURN_CELL_OBJECTS set to true
    Configuration::ROWS_TO_LOAD => [],
    Configuration::SKIP_MISSING_CELLS => true,
    Configuration::SKIP_MISSING_ROWS => true,
    Configuration::USE_CELL_ADDRESS => true,
    Configuration::USE_DATE_SYSTEM_1900 => false,
    Configuration::WORKSHEETS_TO_LOAD => [],
];

$reader = new XlsxReader(, $configuration);
```

... or by using the following fluent helper methods on an `XlsxReader` instance:

- `columns()` (default: `[]`)
- `customFormats()` (default: `[]`)
- `includeMissingCells()`
- `skipMissingCells()` (default)
- `includeMissingRows()`
- `skipMissingRows()` (default)
- `returnCellObjects(bool $readFormulas = false, bool $readHyperlinks = false)`
- `rows()` (default: `[]`)
- `useCellAddress()` (default)
- `useColumnIndex()`
- `useDateSystem1900()` (default)
- `useDateSystem1904()`
- `worksheets()` (default: `[]`)

### `customFormats()`: Apply custom formatting

[](#customformats-apply-custom-formatting)

By default date/time values are returned as DateTime objects and numbers as integer or float, no formatting is applied.

Formatting can be applied by supplying an array of closures that are called depending on the format ID or format string associated with the number format of the cell.

Caution

Format strings displayed in spreadsheet applications are usually localized but stored in US English format in the files. The library expects format strings as they appear in the file. E.g. the format `TT.MM.JJ hh:mm:ss` in a German UI would be stored as `dd/mm/yy\ hh:mm:ss` in the file.

The closure receives the following arguments:

```
function (mixed $value, string $rawValue, string $cellAddress, string $worksheetName)
```

- `$rawValue` contains the raw string from the cell value that has been read from the file.
- `$value` contains the value that would be returned by default from the library, i.e. int/float/string/DateTime.
- `$cellAddress` contains the cell address (e.g. `'A7'`).
- `$worksheetName` contains the name of the worksheet (e.g. `'Sheet1'`).

The default format IDs can be found in the array `Styles::BUILTIN_FORMATS`.

The default is an empty array (`[]`).

```
use SaschaKliche\PhpXlsxReader\XlsxReader;

$reader = new XlsxReader();
$reader->open();

$data = $reader->customFormats([
    //  => static fn(mixed $value, string $rawValue) => $value,
    '9' => static fn(int $number) => number_format($number * 100, 2) . '%',
    '14' => static fn(DateTime $date) => $date->format('d.m.Y'),
    // format string
    // '0%' => static fn(int $number) => number_format($number * 100, 2) . '%', // same as index '9'
    '#,##0.00' => static fn(float $number) => number_format($number, 2),
])->readAsArray();

// values for cells with number format 14 ('mm-dd-yy')
// will not be returned as DateTime objects but
// as formatted date strings
```

### `includeMissingCells()`: Include missing cells

[](#includemissingcells-include-missing-cells)

The equivalent of setting the option `Configuration::IGNORE_MISSING_CELLS` to `true`.

```
use SaschaKliche\PhpXlsxReader\XlsxReader;

$reader = new XlsxReader();

$data = $reader
    ->open()
    ->includeMissingCells()
    ->readAsArray();
```

### `skipMissingCells()`: Ignore missing cells

[](#skipmissingcells-ignore-missing-cells)

The equivalent of setting the option `Configuration::IGNORE_MISSING_CELLS` to `true`.

This is the default configuration.

```
use SaschaKliche\PhpXlsxReader\XlsxReader;

$reader = new XlsxReader();

$data = $reader
    ->open();
    ->skipMissingCells()
    ->readAsArray();
```

### `includeMissingRows()`: Include missing rows

[](#includemissingrows-include-missing-rows)

The equivalent of setting the option `Configuration::IGNORE_MISSING_ROWS` to `true`.

```
use SaschaKliche\PhpXlsxReader\XlsxReader;

$reader = new XlsxReader();

$data = $reader
    ->open()
    ->includeMissingRows()
    ->readAsArray();
```

### `skipMissingRows()`: Ignore missing rows

[](#skipmissingrows-ignore-missing-rows)

The equivalent of setting the option `Configuration::IGNORE_MISSING_ROWS` to `true`.

This is the default configuration.

```
use SaschaKliche\PhpXlsxReader\XlsxReader;

$reader = new XlsxReader();

$data = $reader
    ->open()
    ->skipMissingRows()
    ->readAsArray();
```

### `returnCellObjects()`: Return Cell object instances instead of cell values

[](#returncellobjects-return-cell-object-instances-instead-of-cell-values)

The equivalent of setting the option `Configuration::RETURN_CELL_OBJECTS` to `true`.

If this is set to `true` (default is `false`) an instance of the `Cell` class will be returned for each cell instead of the cell's value (`int`/`float`/`string`/`DateTime` or value formatted by a `customFormats` closure).

Optionally, formulas and hyperlinks can be read when `Cell` objects are returned. Hyperlinks have a performance impact because they require additional read operations on the XLSX file contents. That performance impact might be noticable on very large worksheets. Reading formulas and hyperlinks is disabled by default.

```
use SaschaKliche\PhpXlsxReader\XlsxReader;

$reader = new XlsxReader();
$reader->open();

// don't read formulas and hyperlinks
$data = $reader->returnCellObjects()->readAsArray();

// read formulas and hyperlinks
$data = $reader->returnCellObjects(readFormulas: true, readHyperlinks: true)->readAsArray();

// $data[][][][]
```

See "[Cell objects](#cell-objects)" for details about the `Cell` objects.

### `useCellAddress()`: Indexing cells by cell address

[](#usecelladdress-indexing-cells-by-cell-address)

The equivalent of setting the option `Configuration::USE_CELL_ADDRESS` to `true`.

```
use SaschaKliche\PhpXlsxReader\XlsxReader;

$reader = new XlsxReader();

$data = $reader
    ->open()
    ->useCellAddress()
    ->readAsArray();

// $data[][][][]
```

### `useColumnIndex()`: Indexing cells by column index number

[](#usecolumnindex-indexing-cells-by-column-index-number)

The equivalent of setting the option `Configuration::USE_CELL_ADDRESS` to `false`.

```
use SaschaKliche\PhpXlsxReader\XlsxReader;

$reader = new XlsxReader();

$data = $reader
    ->open()
    ->useCellAddress()
    ->readAsArray();

// $data[][][][]
```

### `useDateSystem1900()`: Use 1900 date system

[](#usedatesystem1900-use-1900-date-system)

The equivalent of setting the option `Configuration::USE_DATE_SYSTEM_1900` to `true`.

The date system used by the XLSX file should be detected automatically. If date values are not calculate correctly, try setting it explicitly.

This is the default configuration.

```
use SaschaKliche\PhpXlsxReader\XlsxReader;

$reader = new XlsxReader();

$data = $reader
    ->open()
    ->useDateSystem1900()
    ->readAsArray();
```

### `useDateSystem1904()`: Use 1904 date system

[](#usedatesystem1904-use-1904-date-system)

The equivalent of setting the option `Configuration::USE_DATE_SYSTEM_1900` to `false`.

The date system used by the XLSX file should be detected automatically. If date values are not calculate correctly, try setting it explicitly.

```
use SaschaKliche\PhpXlsxReader\XlsxReader;

$reader = new XlsxReader();

$data = $reader
    ->open()
    ->useDateSystem1904()
    ->readAsArray();
```

### `columns()`: Selecting the columns to load from the worksheets

[](#columns-selecting-the-columns-to-load-from-the-worksheets)

The equivalent of setting the option `Configuration::COLUMNS_TO_LOAD`.

If only specific rows from a worksheet are needed, those rows can be requested using `columns()` by providing an array of row index numbers.

Columns can either be requested "globally" for each existing worksheet ...

```
use SaschaKliche\PhpXlsxReader\XlsxReader;

$reader = new XlsxReader();

$data = $reader
    ->open()
    ->columns([2, 3, 4, 5])
    ->readAsArray();
```

... or explicitly for a specific worksheet ...

```
use SaschaKliche\PhpXlsxReader\XlsxReader;

$reader = new XlsxReader();

$data = $reader
    ->open()
    ->columns(['Sheet1' => [2, 3, 4, 5]])
    ->readAsArray();
```

The columns can be listed individually as shown above or providing `min` and/or `max` values:

```
use SaschaKliche\PhpXlsxReader\XlsxReader;

$reader = new XlsxReader();
$reader->open();

$reader->columns([Configuration::MIN => 3])->readAsArray();
$reader->columns(['Sheet1' => [Configuration::MIN => 3]])->readAsArray();

$reader->columns([Configuration::MIN => 2, Configuration::MAX => 5])->readAsArray();
// same as $reader->columns([2, 3, 4, 5])->readAsArray();
$reader->columns(['Sheet1' => [Configuration::MIN => 2, Configuration::MAX => 5]])->readAsArray();
// same as $reader->columns(['Sheet1' => [2, 3, 4, 5]])->readAsArray();
```

By default, non existing columns will not be returned even if they are requested. `includeMissingColumns()` can be used to have them returned as long as they are not beyond the last existing column on the worksheet.

```
use SaschaKliche\PhpXlsxReader\XlsxReader;

$reader = new XlsxReader();

$data = $reader
    ->open()
    ->includeMissingCells()
    ->columns(['Sheet1' => [2, 3, 4, 5]])
    ->readAsArray();
```

Caution

Columns that have been requested beyond the last existing column in a row will not be returned! E.g. a row has columns 1 - 5, requesting column 6 will not return a column 6.
Exception: If a header row is being used ([`XlsxReader::readWithHeader()`](#readwithheader-reading-a-workbook-with-header-row-as-an-associative-array)) a cell for each header will be returned for each row on the worksheet.

The default is an empty array (`[]`) meaning all existing columns are loaded.

### `rows()`: Selecting the rows to load from the worksheets

[](#rows-selecting-the-rows-to-load-from-the-worksheets)

The equivalent of setting the option `Configuration::ROWS_TO_LOAD`.

If only specific rows from a worksheet are needed, those rows can be requested using `rows()` by providing an array of row index numbers.

Rows can either be requested "globally" for each existing worksheet ...

```
use SaschaKliche\PhpXlsxReader\XlsxReader;

$reader = new XlsxReader();

$data = $reader
    ->open()
    ->rows([2, 3, 4, 5])
    ->readAsArray();
```

... or explicitly for a specific worksheet ...

```
use SaschaKliche\PhpXlsxReader\XlsxReader;

$reader = new XlsxReader();

$data = $reader
    ->open()
    ->rows(['Sheet1' => [2, 3, 4, 5]])
    ->readAsArray();
```

By default, non existing rows will not be returned even if they are requested. `includeMissingRows()` can be used to have them returned as long as they are not beyond the last existing row on the worksheet.

```
use SaschaKliche\PhpXlsxReader\XlsxReader;

$reader = new XlsxReader();

$data = $reader
    ->open()
    ->includeMissingRows()
    ->rows(['Sheet1' => [2, 3, 4, 5]])
    ->readAsArray();
```

Caution

Rows that have been requested beyond the last existing row on a worksheet will not be returned! E.g. a worksheet has rows 1 - 5, requesting row 6 will not return a row 6.

The default is an empty array (`[]`) meaning all existing rows are loaded.

### `worksheets()`: Selecting the worksheets to load from a workbook

[](#worksheets-selecting-the-worksheets-to-load-from-a-workbook)

The equivalent of setting the option `Configuration::WORKSHEETS_TO_LOAD`.

The default is an empty array (`[]`) meaning all worksheets are loaded.

```
use SaschaKliche\PhpXlsxReader\XlsxReader;

$reader = new XlsxReader();

$sheet1 = $reader
    ->open()
    ->worksheets(['sheet1', 'sheet2'])
    ->readAsArray();

// $data['sheet1'][][]
// $data['sheet2'][][]
```

Cell objects
------------

[](#cell-objects)

If the option `Configuration::RETURN_CELL_OBJECTS` is set to `true`,

The `Cell` class provides the following methods:

```
__toString(): string
getAddress(): string
getCellFormatString(): string
getColumnIndex(): int
getDataType(): int
getFormula(): string|null
getHyperlinkTarget(): string|null
getRawValue(): string
getRowIndex(): int
getValue(): string
```

### `Cell::getRawValue()`

[](#cellgetrawvalue)

The raw value returned by `getRawValue()` is the value read from the XLSX file, it is always a string.

For cells containing strings this will return a string with the index number of the shared strings file entry. E.g. `'7'`.

For cells containing numbers this will return a string with the numeric representation which can be in exponential notation. E.g. `'3.14'` or `'-42'`.

For cells containing date/time values this will return a string with a numeric value based on the date system of the file. E.g. `'46113'` for 2026-04-01 00:00:00 or `'27106.801655092593'` for 1974-03-18 19:14:23.

### `Cell::getValue()`

[](#cellgetvalue)

The value returned by `getValue()` is either an `int`/`float`/`string`/`DateTime` or a custom value returned by a formatting closure provided by `customFormats`.

### `Cell::getCellFormatString()`

[](#cellgetcellformatstring)

`getCellFormatString()` returns the format string associated with the cell. E.g. `0%` for cells containing numeric values in percentage notation or `#,##0.00` for numeric values with thousands separators and two decimals.

Caution

Format strings displayed in spreadsheet applications are usually localized but stored in US English format in the files. `Cell::getCellFormatString()` returns format strings as they appear in the file. E.g. the format `TT.MM.JJ hh:mm:ss` in a German UI would be stored as `dd/mm/yy\ hh:mm:ss` in the file and returned in that format by the library.

### `Cell::getFormula()`

[](#cellgetformula)

Formulas are only read if `readFormulas` is set to `true` on [`returnCellObjects()`](#returncellobjects-return-cell-object-instances-instead-of-cell-values)or directly via `Configuration::READ_FORMULAS`.

`getFormula()` returns the cell's formula or null if the cell doesn't have a formula. E.g. `'SUM(A2:C2)'` or `'SUBTOTAL(101,Tabelle1[Column A])'`.

### `Cell::getHyperlinkTarget()`

[](#cellgethyperlinktarget)

Formulas are only read if `readHyperlinks` is set to `true` on [`returnCellObjects()`](#returncellobjects-return-cell-object-instances-instead-of-cell-values)or directly via `Configuration::READ_HYPERLINKS`.

`getHyperlinkTarget()` returns the hyperlink's target or null if the cell doesn't have a hyperlink. E.g. `'https://github.com/'`.

### `Cell::getAddress()`, `Cell::getColumnIndex()`, `Cell::getRowIndex()`

[](#cellgetaddress-cellgetcolumnindex-cellgetrowindex)

`getAddress()` returns the cell's address, e.g. `C3`. `getRowIndex()` and `getColumnIndex()` return the 1-based numeric index, e.g. for cell `D3` the method `getRowIndex()` returns 3 and `getColumnIndex()` returns 4. Both address and index numbers are always provided, there is no need to configure `Configuration::USE_CELL_ADDRESS`.

### `Cell::getDataType()`

[](#cellgetdatatype)

The `getDataType()` method returns one of the following values depending on the type of data that has been detected:

```
Cell::DATA_TYPE_UNKNOWN = 0
Cell::DATA_TYPE_DATETIME = 1
Cell::DATA_TYPE_FLOAT = 2
Cell::DATA_TYPE_INTEGER = 3
Cell::DATA_TYPE_STRING = 4
```

Performance considerations
--------------------------

[](#performance-considerations)

Large files can have a serious impact on both runtime duration and memory usage. Files containing a lot of (different) text will use a lot of memory. The text is stored in a shared strings files within the XLSX file and is read into memory completely to be able to return the text values. Files containing a small amount of (different) text will use significantly less memory.

By default all options that could have a performance impact are disabled, e.g. reading hyperlinks.

The duration and memory usage are recorded by default and can be retrieved from the `XlsxReader` instance:

```
use SaschaKliche\PhpXlsxReader\XlsxReader;

$reader = new XlsxReader();

$data = $reader
    ->open()
    ->readWithHeader();

$duration = $reader->getDurationInSeconds();   // float
$memory = $reader->getMemoryUsage();           // int
$peak = $reader->getMemoryPeakUsage();         // int

$reader->printPerformanceData();
// example output:
// Duration: 0.000343458 seconds
// Memory: 14.17 MiB
// Peak memory: 14.19 MiB
```

Limitations
-----------

[](#limitations)

The library is pretty "dumb" to keep it small and simple. Therefore a lot of information is currently ignored / not retrieved and some features are not supported. Examples:

- Comments
- Conditional formatting
- Column spans are ignored, i.e. retrieved columns might contain a `null` value
- Complex / non-standard file layouts, e.g. multiple shared string files
- Defined names
- Embedded documents
- Encrypted files
- Filters
- Fixed rows and columns
- Images, pictures, charts, cell styles
- Information about fonts, alignment, borders, indentation, column width / row height, and colors
- Macro code
- Page layout like print areas, headers, footers
- Pivot charts and tables
- Revisions / tracked changes
- Sorting
- Validation

Caution

The library might not be able to correctly read files using these features.

References
----------

[](#references)

- [Office Implementation Information for ISO/IEC 29500 Standards Support](https://learn.microsoft.com/en-us/openspecs/office_standards/ms-oi29500/1fd4a662-8623-49c0-82f0-18fa91b413b8)
- [ECMA-376 Fifth Edition, Part 1](https://www.ecma-international.org/publications-and-standards/standards/ecma-376/)

###  Health Score

40

—

FairBetter than 86% of packages

Maintenance91

Actively maintained with recent releases

Popularity4

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity52

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% 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 ~5 days

Total

4

Last Release

42d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/3383ea7948ec1e9337df6240eabffa3e1732480bf17e55ae37badeb69d0a95b5?d=identicon)[SaschaKliche](/maintainers/SaschaKliche)

---

Top Contributors

[![SaschaKliche](https://avatars.githubusercontent.com/u/22022118?v=4)](https://github.com/SaschaKliche "SaschaKliche (16 commits)")

---

Tags

libraryooxmlphpspreadsheetxlsxphpxlsxOOXMLspreadsheet

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/saschakliche-phpxlsxreader/health.svg)

```
[![Health](https://phpackages.com/badges/saschakliche-phpxlsxreader/health.svg)](https://phpackages.com/packages/saschakliche-phpxlsxreader)
```

###  Alternatives

[openspout/openspout

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

1.2k65.5M205](/packages/openspout-openspout)

PHPackages © 2026

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