PhpSpreadsheet File I/O: Reading and Writing Various Formats

File Reading and Writing

As you know from the architecture, the basic PhpSpreadsheet class cannot perform read/write operations on persistent storage. For this purpose, PhpSpreadsheet provides readers and writers, which implement \PhpOffice\PhpSpreadsheet\Reader\IReader and \PhpOffice\PhpSpreadsheet\Writer\IWriter.

\PhpOffice\PhpSpreadsheet\IOFactory

The PhpSpreadsheet API provides several methods for creating \PhpOffice\PhpSpreadsheet\Reader\IReader or \PhpOffice\PhpSpreadsheet\Writer\IWriter instances:

Through direct creation of \PhpOffice\PhpSpreadsheet\IOFactory. All examples below demonstrate the direct creation method. Note that you can also use the \PhpOffice\PhpSpreadsheet\IOFactory class to do this.

Creating \PhpOffice\PhpSpreadsheet\Reader\IReader using \PhpOffice\PhpSpreadsheet\IOFactory

There are two ways to read files into PhpSpreadsheet: using automatic file type detection or explicitly.

Automatic file type detection allows \PhpOffice\PhpSpreadsheet\Reader\IReader to check different distributions. If one can load the specified filename, that \PhpOffice\PhpSpreadsheet\Reader\IReader is used to load the file. Explicit mode requires you to specify which \PhpOffice\PhpSpreadsheet\Reader\IReader should be used.

You can create a \PhpOffice\PhpSpreadsheet\Reader\IReader instance in automatic file type detection mode using \PhpOffice\PhpSpreadsheet\IOFactory with the following code example:

$spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load("05featuredemo.xlsx");

This functionality is typically used when you need to read user-uploaded files and you don't know whether they're uploading xls or xlsx files.

If you need to set some properties on the reader (such as read data only, see more content later), you can use the following variant instead:

$reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReaderForFile("05featuredemo.xlsx");
$reader->setReadDataOnly(true);
$reader->load("05featuredemo.xlsx");

You can create a \PhpOffice\PhpSpreadsheet\Reader\IReader instance using \PhpOffice\PhpSpreadsheet\IOFactory in explicit mode with the following code example:

$reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader("Xlsx");
$spreadsheet = $reader->load("05featuredemo.xlsx");

Note that automatic type detection mode is slightly slower than explicit mode.

Creating \PhpOffice\PhpSpreadsheet\Writer\IWriter using \PhpOffice\PhpSpreadsheet\IOFactory

You can create a \PhpOffice\PhpSpreadsheet\Writer\IWriter instance using \PhpOffice\PhpSpreadsheet\IOFactory:

$writer = \PhpOffice\PhpSpreadsheet\IOFactory::createWriter($spreadsheet, "Xlsx");
$writer->save("05featuredemo.xlsx");

Excel 2007 (SpreadsheetML) File Format

The Xlsx file format is the primary file format for PhpSpreadsheet. It allows outputting an in-memory spreadsheet to an .xlsx file.

\PhpOffice\PhpSpreadsheet\Reader\Xlsx

Reading Spreadsheets

You can read an .xlsx file using the following code:

$reader = new \PhpOffice\PhpSpreadsheet\Reader\Xlsx();
$spreadsheet = $reader->load("05featuredemo.xlsx");

Reading Data Only

You can set the option setReadDataOnly on the reader to indicate that the reader should ignore styles, data validation, etc., and only read cell data:

$reader = new \PhpOffice\PhpSpreadsheet\Reader\Xlsx();
$reader->setReadDataOnly(true);
$spreadsheet = $reader->load("05featuredemo.xlsx");

Reading Only Specific Worksheets

You can set the option setLoadSheetsOnly on the reader to indicate that the reader should only load sheets with given names:

$reader = new \PhpOffice\PhpSpreadsheet\Reader\Xlsx();
$reader->setLoadSheetsOnly(["Sheet 1", "My special sheet"]);
$spreadsheet = $reader->load("05featuredemo.xlsx");

Reading Only Specific Cells

You can set the option setReadFilter on the reader to indicate that the reader should only load cells matching given rules. The read filter can be any class implementing \PhpOffice\PhpSpreadsheet\Reader\IReadFilter. By default, \PhpOffice\PhpSpreadsheet\Reader\DefaultReadFilter is used which reads all cells.

The following code will only read row 1 and rows 20-30 of any worksheet in the Excel file:

class MyReadFilter implements \PhpOffice\PhpSpreadsheet\Reader\IReadFilter {

    public function readCell($column, $row, $worksheetName = '') {
        // Read title row and rows 20 - 30
        if ($row == 1 || ($row >= 20 && $row <= 30)) {
            return true;
        }
        return false;
    }
}

$reader = new \PhpOffice\PhpSpreadsheet\Reader\Xlsx();
$reader->setReadFilter( new MyReadFilter() );
$spreadsheet = $reader->load("06largescale.xlsx");

\PhpOffice\PhpSpreadsheet\Writer\Xlsx

Writing Spreadsheets

You can write an .xlsx file using the following code:

$writer = new \PhpOffice\PhpSpreadsheet\Writer\Xlsx($spreadsheet);
$writer->save("05featuredemo.xlsx");

Formula Pre-calculation

By default, the writer pre-calculates all formulas in the spreadsheet. On large spreadsheets, this can be slow, or even unnecessary. However, you can disable formula pre-calculation:

$writer = new \PhpOffice\PhpSpreadsheet\Writer\Xlsx($spreadsheet);
$writer->setPreCalculateFormulas(false);
$writer->save("05featuredemo.xlsx");

Office 2003 Compatibility Pack

Due to bugs in the Office 2003 Compatibility Pack, there may be some minor issues when opening Xlsx spreadsheets (primarily related to formula calculation). You can enable Office 2003 compatibility:

$writer = new \PhpOffice\PhpSpreadsheet\Writer\Xlsx($spreadsheet);
$writer->setOffice2003Compatibility(true);
$writer->save("05featuredemo.xlsx");

Office 2003 compatibility should only be used when necessary The Office 2003 compatibility option should only be used when necessary. This option disables several Office 2007 file format options, resulting in a less functional Office 2007 spreadsheet when using this option.

Excel 5 (BIFF) File Format

The Xls file format is the old Excel file format, implemented in PhpSpreadsheet to provide a unified way to create both .xlsx and .xls files. It's basically a modified version of PEAR Spreadsheet_Excel_Writer, although it has been extended and has fewer restrictions and more functionality than the old PEAR library. This can read all BIFF versions using OLE2: BIFF8, BIFF5 (introduced by Office 95), but cannot read earlier versions.

The Xls file format will no longer be developed; it's just provided for PhpSpreadsheet as another file format.

Excel5 (BIFF) limitations Note that the BIFF file format has some limitations in styling cells and processing large spreadsheets through PHP.

\PhpOffice\PhpSpreadsheet\Reader\Xls

Reading Spreadsheets

You can read an .xls file using the following code:

$reader = new \PhpOffice\PhpSpreadsheet\Reader\Xls();
$spreadsheet = $reader->load("05featuredemo.xls");

Reading Data Only

You can set the option setReadDataOnly on the reader to indicate that the reader should ignore styles, data validation, etc., and only read cell data:

$reader = new \PhpOffice\PhpSpreadsheet\Reader\Xls();
$reader->setReadDataOnly(true);
$spreadsheet = $reader->load("05featuredemo.xls");

Reading Only Specific Worksheets

You can set the option setLoadSheetsOnly on the reader to indicate that the reader should only load sheets with given names:

$reader = new \PhpOffice\PhpSpreadsheet\Reader\Xls();
$reader->setLoadSheetsOnly(["Sheet 1", "My special sheet"]);
$spreadsheet = $reader->load("05featuredemo.xls");

Reading Only Specific Cells

You can set the option setReadFilter on the reader to indicate that the reader should only load cells matching given rules. The read filter can be any class implementing \PhpOffice\PhpSpreadsheet\Reader\IReadFilter. By default, \PhpOffice\PhpSpreadsheet\Reader\DefaultReadFilter is used which reads all cells.

The following code will only read row 1 and rows 20-30 of any worksheet in the Excel file:

class MyReadFilter implements \PhpOffice\PhpSpreadsheet\Reader\IReadFilter {

    public function readCell($column, $row, $worksheetName = '') {
        // Read title row and rows 20 - 30
        if ($row == 1 || ($row >= 20 && $row <= 30)) {
            return true;
        }
        return false;
    }
}

$reader = new \PhpOffice\PhpSpreadsheet\Reader\Xls();
$reader->setReadFilter( new MyReadFilter() );
$spreadsheet = $reader->load("06largescale.xls");

\PhpOffice\PhpSpreadsheet\Writer\Xls

Writing Spreadsheets

You can write an .xls file using the following code:

$writer = new \PhpOffice\PhpSpreadsheet\Writer\Xls($spreadsheet);
$writer->save("05featuredemo.xls");

Excel 2003 XML File Format

The Excel 2003 XML file format is a file format that can be used in older versions of Microsoft Excel.

Excel 2003 XML limitations Note that the Excel 2003 XML format has some limitations in styling cells and processing large spreadsheets through PHP.

\PhpOffice\PhpSpreadsheet\Reader\Xml

Reading Spreadsheets

You can read an Excel 2003 .xml file using the following code:

$reader = new \PhpOffice\PhpSpreadsheet\Reader\Xml();
$spreadsheet = $reader->load("05featuredemo.xml");

Reading Only Specific Cells

You can set the option setReadFilter on the reader to indicate that the reader should only load cells matching given rules. The read filter can be any class implementing \PhpOffice\PhpSpreadsheet\Reader\IReadFilter. By default, \PhpOffice\PhpSpreadsheet\Reader\DefaultReadFilter is used which reads all cells.

The following code will only read row 1 and rows 20-30 of any worksheet in the Excel file:

class MyReadFilter implements \PhpOffice\PhpSpreadsheet\Reader\IReadFilter {

    public function readCell($column, $row, $worksheetName = '') {
        // Read title row and rows 20 - 30
        if ($row == 1 || ($row >= 20 && $row <= 30)) {
            return true;
        }
        return false;
    }

}

$reader = new \PhpOffice\PhpSpreadsheet\Reader\Xml();
$reader->setReadFilter( new MyReadFilter() );
$spreadsheet = $reader->load("06largescale.xml");

Symbolic Link (SYLK)

Symbolic Link (SYLK) is a Microsoft file format, typically used for exchanging data between applications, especially spreadsheets. SYLK files usually have a .slk extension. It consists only of displayable ANSI characters and can be easily created and processed by other applications (such as databases).

SYLK limitations Note that the SYLK file format has some limitations in styling cells and processing large spreadsheets through PHP.

\PhpOffice\PhpSpreadsheet\Reader\Slk

Reading Spreadsheets

You can read a .slk file using the following code:

$reader = new \PhpOffice\PhpSpreadsheet\Reader\Slk();
$spreadsheet = $reader->load("05featuredemo.slk");

Reading Only Specific Cells

You can set the option setReadFilter on the reader to indicate that the reader should only load cells matching given rules. The read filter can be any class implementing \PhpOffice\PhpSpreadsheet\Reader\IReadFilter. By default, \PhpOffice\PhpSpreadsheet\Reader\DefaultReadFilter is used which reads all cells.

The following code will only read row 1 and rows 20-30 of any worksheet in the SYLK file:

class MyReadFilter implements \PhpOffice\PhpSpreadsheet\Reader\IReadFilter {

    public function readCell($column, $row, $worksheetName = '') {
        // Read title row and rows 20 - 30
        if ($row == 1 || ($row >= 20 && $row <= 30)) {
            return true;
        }
        return false;
    }

}

$reader = new \PhpOffice\PhpSpreadsheet\Reader\Slk();
$reader->setReadFilter( new MyReadFilter() );
$spreadsheet = $reader->load("06largescale.slk");

Open/Libre Office (.ods)

Open Office or Libre Office .ods files are the standard file format for Open Office or Libre Office Calc files.

\PhpOffice\PhpSpreadsheet\Reader\Ods

Reading Spreadsheets

You can read an .ods file using the following code:

$reader = new \PhpOffice\PhpSpreadsheet\Reader\Ods();
$spreadsheet = $reader->load("05featuredemo.ods");

Reading Only Specific Cells

You can set the option setReadFilter on the reader to indicate that the reader should only load cells matching given rules. The read filter can be any class implementing \PhpOffice\PhpSpreadsheet\Reader\IReadFilter. By default, \PhpOffice\PhpSpreadsheet\Reader\DefaultReadFilter is used which reads all cells.

The following code will only read row 1 and rows 20-30 of any worksheet in the Calc file:

class MyReadFilter implements \PhpOffice\PhpSpreadsheet\Reader\IReadFilter {

    public function readCell($column, $row, $worksheetName = '') {
        // Read title row and rows 20 - 30
        if ($row == 1 || ($row >= 20 && $row <= 30)) {
            return true;
        }
        return false;
    }

}

$reader = new PhpOffice\PhpSpreadsheet\Reader\Ods();
$reader->setReadFilter( new MyReadFilter() );
$spreadsheet = $reader->load("06largescale.ods");

CSV (Comma Separated Values)

CSV (Comma Separated Values) is commonly used as an import/export file format with other systems. PhpSpreadsheet allows reading and writing CSV files.

CSV limitations Note that the CSV file format has some limitations in styling cells, number formats, etc.

\PhpOffice\PhpSpreadsheet\Reader\Csv

Reading CSV Files

You can read a .csv file using the following code:

$reader = new \PhpOffice\PhpSpreadsheet\Reader\Csv();
$spreadsheet = $reader->load("sample.csv");

Setting CSV Options

CSV files are often not truly "comma-separated", or use semicolon (;) as delimiter. You can indicate some options to \PhpOffice\PhpSpreadsheet\Reader\Csv before reading the CSV file.

The delimiter will be auto-detected, so in most cases, you don't need to specify a delimiter. However, if auto-detection doesn't suit your use case, you can set it manually.

Please note that \PhpOffice\PhpSpreadsheet\Reader\Csv assumes by default that the loaded CSV file is UTF-8 encoded. If you're reading a CSV file created in Microsoft Office Excel, the correct input encoding might be Windows-1252 (CP1252). Always ensure the input encoding is set correctly.

$reader = new \PhpOffice\PhpSpreadsheet\Reader\Csv();
$reader->setInputEncoding('CP1252');
$reader->setDelimiter(';');
$reader->setEnclosure('');
$reader->setSheetIndex(0);

$spreadsheet = $reader->load("sample.csv");

Reading Specific Worksheets

CSV files can only contain one worksheet. Therefore, you can specify which worksheet to read from the CSV:

$reader->setSheetIndex(0);

Loading into Existing Spreadsheet

When working with CSV files, you might encounter situations where you want to import CSV data into an existing Spreadsheet object. The following code will load the CSV file into the existing $spreadsheet containing some worksheets, and import it into the 6th worksheet:

$reader = new \PhpOffice\PhpSpreadsheet\Reader\Csv();
$reader->setDelimiter(';');
$reader->setEnclosure('');
$reader->setSheetIndex(5);

$reader->loadIntoExisting("05featuredemo.csv", $spreadsheet);

\PhpOffice\PhpSpreadsheet\Writer\Csv

Writing CSV Files

You can write a .csv file using the following code:

$writer = new \PhpOffice\PhpSpreadsheet\Writer\Csv($spreadsheet);
$writer->save("05featuredemo.csv");

Setting CSV Options

CSV files are often not truly "comma-separated", or use semicolon (;) as delimiter. You can indicate some options to \PhpOffice\PhpSpreadsheet\Writer\Csv before writing the CSV file:

$writer = new \PhpOffice\PhpSpreadsheet\Writer\Csv($spreadsheet);
$writer->setDelimiter(';');
$writer->setEnclosure('');
$writer->setLineEnding("\r\n");
$writer->setSheetIndex(0);

$writer->save("05featuredemo.csv");

Writing a Specific Worksheet

CSV files can only contain one worksheet. Therefore, you can specify which worksheet to write to CSV:

$writer->setSheetIndex(0);

Formula Pre-calculation

By default, the writer pre-calculates all formulas in the spreadsheet. On large spreadsheets, this can be slow, or even unnecessary. However, you can disable formula pre-calculation:

$writer = new \PhpOffice\PhpSpreadsheet\Writer\Csv($spreadsheet);
$writer->setPreCalculateFormulas(false);
$writer->save("05featuredemo.csv");

Writing UTF-8 CSV Files

CSV files can be marked as UTF-8 by writing a BOM header. You can enable this with the following code:

$writer = new \PhpOffice\PhpSpreadsheet\Writer\Csv($spreadsheet);
$writer->setUseBOM(true);
$writer->save("05featuredemo.csv");

Decimal and Thousand Separators

If the worksheet you're exporting contains numbers with decimal or thousand separators, you should consider what characters you want to use for those before exporting.

By default, PhpSpreadsheet looks in the server's locale to decide which characters to use. However to avoid issues, it's recommended to explicitly set the characters as shown below.

English users would want to use this before exporting:

\PhpOffice\PhpSpreadsheet\Shared\StringHelper::setDecimalSeparator('.');
\PhpOffice\PhpSpreadsheet\Shared\StringHelper::setThousandsSeparator(',');

German users would want to use the opposite values.

\PhpOffice\PhpSpreadsheet\Shared\StringHelper::setDecimalSeparator(',');
\PhpOffice\PhpSpreadsheet\Shared\StringHelper::setThousandsSeparator('.');

Please note that the above code sets decimal and thousand separators as global options. This will also affect how HTML and PDF exports are done.

HTML

PhpSpreadsheet allows you to read or write spreadsheets in HTML format, to quickly represent the data in them to anyone without a spreadsheet application on their PC, or to load files saved by other scripts that just create HTML markup and give them an .xls file extension.

HTML limitations Note that the HTML file format has some limitations in styling cells, number formats, etc.

\PhpOffice\PhpSpreadsheet\Reader\Html

Reading Spreadsheets

You can read an .html or .htm file using the following code:

$reader = new \PhpOffice\PhpSpreadsheet\Reader\Html();

$spreadsheet = $reader->load("05featuredemo.html");

HTML limitations Note that the HTML reader is still experimental and doesn't yet support clean merged cells or nested tables

\PhpOffice\PhpSpreadsheet\Writer\Html

Please note that \PhpOffice\PhpSpreadsheet\Writer\Html only outputs the first worksheet by default.

Writing Spreadsheets

You can write an .htm file using the following code:

$writer = new \PhpOffice\PhpSpreadsheet\Writer\Html($spreadsheet);

$writer->save("05featuredemo.htm");

Writing All Worksheets

HTML files can contain one or more worksheets. If you want to write all worksheets to a single HTML file, use the following code:

$writer->writeAllSheets();

Writing a Specific Worksheet

HTML files can contain one or more worksheets. Therefore, you can specify which worksheet to write to HTML:

$writer->setSheetIndex(0);

Setting the Image Root Directory for HTML Files

In some cases, you need to explicitly set the root directory for included images. For example, instead of:

html <img src="./images/logo.jpg">

You might want to see:

<img src="http://www.domain.com/images/logo.jpg">

You can achieve this result with the following code:

$writer->setImagesRoot('http://www.example.com');

Formula Pre-calculation

By default, the writer pre-calculates all formulas in the spreadsheet. On large spreadsheets, this can be slow, or even unnecessary. However, you can disable formula pre-calculation:

$writer = new \PhpOffice\PhpSpreadsheet\Writer\Html($spreadsheet);
$writer->setPreCalculateFormulas(false);

$writer->save("05featuredemo.htm");

Embedding Generated HTML in a Web Page

In some cases, you might want to embed the generated HTML into an existing website. \PhpOffice\PhpSpreadsheet\Writer\Html supports generating specific parts of the HTML code only, allowing you to use these parts in your website.

Supported methods:

  • generateHTMLHeader()
  • generateStyles()
  • generateSheetData()
  • generateHTMLFooter()

Here's an example that retrieves all parts independently and merges them into the resulting HTML page:

<?php
$writer = new \PhpOffice\PhpSpreadsheet\Writer\Html($spreadsheet);
echo $writer->generateHTMLHeader();
?>

<style>
<!--
html {
    font-family: Times New Roman;
    font-size: 9pt;
    background-color: white;
}

<?php
echo $writer->generateStyles(false); // do not write <style> and </style>
?>

-->
</style>

<?php
echo $writer->generateSheetData();
echo $writer->generateHTMLFooter();
?>

Writing UTF-8 HTML Files

CSV files can be marked as UTF-8 by writing a BOM header. You can enable this with the following code:

$writer = new \PhpOffice\PhpSpreadsheet\Writer\Html($spreadsheet);
$writer->setUseBOM(true);

$writer->save("05featuredemo.htm");

Decimal and Thousand Separators

See the section on how to control their appearance in \PhpOffice\PhpSpreadsheet\Writer\Csv.

PDF Format

PhpSpreadsheet allows you to write spreadsheets in PDF format to quickly distribute the represented data.

PDF limitations Note that the PDF file format has some limitations in styling cells, number formats, etc.

\PhpOffice\PhpSpreadsheet\Writer\Pdf

PhpSpreadsheet's PDF Writer is a wrapper for third-party PDF rendering libraries (such as TCPDF, mPDF or Dompdf). You must install the PDF rendering library yourself now. But PhpSpreadsheet can work with many different libraries.

Currently, the following libraries are supported:

Library Downloadable from PhpSpreadsheet Writer
TCPDF https://github.com/tecnickcom/tcpdf Tcpdf
mPDF https://github.com/mpdf/mpdf Mpdf
Dompdf https://github.com/dompdf/dompdf Dompdf

Different libraries have different advantages and disadvantages. Some generate better formatted output than others, some are faster or use less memory than others, and some generate smaller .pdf files. Which one you want to use depends on your specific requirements.

You can instantiate the writer by its specific name as follows:

$writer = \PhpOffice\PhpSpreadsheet\IOFactory::createWriter($spreadsheet, 'Mpdf');

Alternatively, you can register the writer you're using with a more generic name, so you don't have to remember which library you chose, and just write a PDF file:

$class = \PhpOffice\PhpSpreadsheet\Writer\Pdf\Mpdf::class;
\PhpOffice\PhpSpreadsheet\IOFactory::registerWriter('Pdf', $class);
$writer = \PhpOffice\PhpSpreadsheet\IOFactory::createWriter($spreadsheet, 'Pdf');

Or you can instantiate your chosen writer directly:

$writer = new \PhpOffice\PhpSpreadsheet\Writer\Pdf\Mpdf($spreadsheet);

Custom Implementation or Configuration

If you need a custom implementation or custom configuration for a supported PDF library. You can extend the PDF library and PDF writer as follows:

class My_Custom_TCPDF extends TCPDF
{
    // ...
}

class My_Custom_TCPDF_Writer extends \PhpOffice\PhpSpreadsheet\Writer\Pdf\Tcpdf
{
    protected function createExternalWriterInstance($orientation, $unit, $paperSize)
    {
        $instance = new My_Custom_TCPDF($orientation, $unit, $paperSize);

        // more configuration of $instance

        return $instance;
    }
}

\PhpOffice\PhpSpreadsheet\IOFactory::registerWriter('Pdf', MY_TCPDF_WRITER::class);

Writing Spreadsheets

Once you've determined which renderer to use for PDF generation, you can write a .pdf file using the following code:

$writer = new \PhpOffice\PhpSpreadsheet\Writer\Pdf\Mpdf($spreadsheet);
$writer->save("05featuredemo.pdf");

Please note that \PhpOffice\PhpSpreadsheet\Writer\Pdf only outputs the first worksheet by default.

Writing All Worksheets

PDF files can contain one or more worksheets. If you want to write all worksheets to a single PDF file, use the following code:

$writer->writeAllSheets();

Writing a Specific Worksheet

PDF files can contain one or more worksheets. Therefore, you can specify which worksheet to write to PDF:

$writer->setSheetIndex(0);

Formula Pre-calculation

By default, the writer pre-calculates all formulas in the spreadsheet. On large spreadsheets, this can be slow, or even unnecessary. However, you can disable formula pre-calculation:

$writer = new \PhpOffice\PhpSpreadsheet\Writer\Pdf\Mpdf($spreadsheet);
$writer->setPreCalculateFormulas(false);

$writer->save("05featuredemo.pdf");

Decimal and Thousand Separators

See the section on how to control their appearance in \PhpOffice\PhpSpreadsheet\Writer\Csv.

Generating Excel Files from Templates (Read, Modify, Write)

Readers and writers are tools that enable you to generate Excel files from templates. This requires less coding work compared to generating Excel files from scratch, especially when your template has many styles, page setup properties, headers, etc.

Here's an example of how to open a template file, fill in a few fields, and save it again:

$spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load('template.xlsx');

$worksheet = $spreadsheet->getActiveSheet();

$worksheet->getCell('A1')->setValue('John');
$worksheet->getCell('A2')->setValue('Smith');

$writer = \PhpOffice\PhpSpreadsheet\IOFactory::createWriter($spreadsheet, 'Xls');
$writer->save('write.xls');

Please note that you can load an xlsx file and generate an xls file.

Generating Excel Files from HTML Content

If you want to generate Excel files from pre-rendered HTML content, you can use the HTML Reader to do this automatically. This is partiuclarly useful when you're generating Excel files from content that will be downloaded/sent to users from a web application.

For example:

$htmlString = '<table>
                  <tr>
                      <td>Hello World</td>
                  </tr>
                  <tr>
                      <td>Hello<br />World</td>
                  </tr>
                  <tr>
                      <td>Hello<br>World</td>
                  </tr>
              </table>';

$reader = new \PhpOffice\PhpSpreadsheet\Reader\Html();
$spreadsheet = $reader->loadFromString($htmlString);

$writer = \PhpOffice\PhpSpreadsheet\IOFactory::createWriter($spreadsheet, 'Xls');
$writer->save('write.xls'); 

Reading Files

Security

When reading spreadsheet files, XML-based formats (such as OfficeOpen XML, Excel2003 XML, OASIS and Gnumeric) are vulnerable to XML External Entity (XXE) injection attacks. This can lead to:

  • Disclosure of file existence
  • Server-side request forgery
  • Command execution (depending on installed PHP wrappers)

To prevent this, by default, each XML-based reader will look for XML entities declared in the DOCTYPE, and if any are found, an exception will be thrown.

Read more about XXE injection.

Loading Spreadsheet Files

The simplest way to load a workbook file is to let PhpSpreadsheet's IO Factory identify the file type and load it, by calling the static load() method of the \PhpOffice\PhpSpreadsheet\IOFactory class.

$inputFileName = './sampleData/example1.xls';

/** Load $inputFileName to a Spreadsheet Object  **/
$spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load($inputFileName);

See samples/Reader/01_Simple_file_reader_using_IOFactory.php for a working example of this code.

The load() method will attempt to identify the file type and instantiate a loader for that file type; using it to load the file and store the data and any formatting in a Spreadsheet object.

The method makes an initial guess at the loader to instantiate based on the file extension; but it will test the file before actually performing the load: so for example, if the file is actually a CSV file or contains HTML markup, but has been given an .xls extension (common), it will reject the loader normally used for .xls files; and test the file with other loaders until it finds one that works, then use that to read the file.

While this is easy to implement in code, you don't have to worry about the file type; this isn't the most efficient method for loading files; and it lacks the flexibility to configure the loader in any way before actually reading the file into a Spreadsheet object.

Creating a Reader and Loading a Spreadsheet File

If you know the file type of the spreadsheet file you need to load, you can instantiate a new reader object for that file type, then use the reader's load() method to read the file as a Spreadsheet object. Each different supported file type can be instantiated by name. However, if the file type is incorrect (e.g. a CSV file with an .xls extension), you may get unpredictable results, although exceptions should generally be caught in such cases.

$inputFileName = './sampleData/example1.xls';

/** Create a new Xls Reader  **/
$reader = new \PhpOffice\PhpSpreadsheet\Reader\Xls();
//    $reader = new \PhpOffice\PhpSpreadsheet\Reader\Xlsx();
//    $reader = new \PhpOffice\PhpSpreadsheet\Reader\Xml();
//    $reader = new \PhpOffice\PhpSpreadsheet\Reader\Ods();
//    $reader = new \PhpOffice\PhpSpreadsheet\Reader\Slk();
//    $reader = new \PhpOffice\PhpSpreadsheet\Reader\Gnumeric();
//    $reader = new \PhpOffice\PhpSpreadsheet\Reader\Csv();
/** Load $inputFileName to a Spreadsheet Object  **/
$spreadsheet = $reader->load($inputFileName);

See samples/Reader/02_Simple_file_reader_using_a_specified_reader.php for a working example of this code.

Alternatively, you can use the IO Factory's createReader() method to instantiate the reader object for you, simply telling it the file type of the reader you want to instantiate.

$inputFileType = 'Xls';
//    $inputFileType = 'Xlsx';
//    $inputFileType = 'Xml';
//    $inputFileType = 'Ods';
//    $inputFileType = 'Slk';
//    $inputFileType = 'Gnumeric';
//    $inputFileType = 'Csv';
$inputFileName = './sampleData/example1.xls';

/**  Create a new Reader of the type defined in $inputFileType  **/
$reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader($inputFileType);
/**  Load $inputFileName to a Spreadsheet Object  **/
$spreadsheet = $reader->load($inputFileName);

See samples/Reader/03_Simple_file_reader_using_the_IOFactory_to_return_a_reader.php for a working example of this code.

If you're not sure of the file type, you can use the IOFactory::identify() method to identify the required reader before using the createReader() method to instantiate the Reader object.

$inputFileName = './sampleData/example1.xls';

/**  Identify the type of $inputFileName  **/
$inputFileType = \PhpOffice\PhpSpreadsheet\IOFactory::identify($inputFileName);
/**  Create a new Reader of the type that has been identified  **/
$reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader($inputFileType);
/**  Load $inputFileName to a Spreadsheet Object  **/
$spreadsheet = $reader->load($inputFileName);

See samples/Reader/04_Simple_file_reader_using_the_IOFactory_to_identify_a_reader_to_use.php for a working example of this code.

Spreadsheet Reader Options

After creating the reader object for the workbook you want to load, you have the opportunity to set additional options before executing the load() method.

Reading Only Data from Spreadsheet Files

If you're only interested in the cell values in the workbook, and don't need any cell format information, you can use the setReadDataOnly() method to set the reader to only read data values and any formulas in each cell.

$inputFileType = 'Xls';
$inputFileName = './sampleData/example1.xls';

/**  Create a new Reader of the type defined in $inputFileType  **/
$reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader($inputFileType);
/**  Advise the Reader that we only want to load cell data  **/
$reader->setReadDataOnly(true);
/**  Load $inputFileName to a Spreadsheet Object  **/
$spreadsheet = $reader->load($inputFileName);

See samples/Reader/05_Simple_file_reader_using_the_read_data_only_option.php for a working example of this code.

It's important to note that workbooks (and PhpSpreadsheet) store dates and times as simple numeric values: they can only be distinguished from other numeric values by the format mask applied to that cell. When setting read data only to true, PhpSpreadsheet doesn't read the cell format mask, so it can't distinguish between dates/times and numbers.

Even when setting read data only to true, the Gnumeric loader has been written to read format masks for date values, so it can distinguish between dates/times and numbers. However, other readers haven't yet implemented this change.

Reading only data from spreadsheet files applies to readers:

Reader Yes/No Reader Yes/No Reader Yes/No
Xlsx Yes Xls Yes Xml Yes
Ods Yes Slk No Gnumeric Yes
CSV No Html No

Reading Only Named Worksheets from Files

If your workbook contains many worksheets, but you're only interested in reading some of them, you can use the setLoadSheetsOnly() method to identify which sheets you're interested in reading.

To read a single sheet, you can pass the sheet name as a parameter to the setLoadSheetsOnly() method.

$inputFileType = 'Xls';
$inputFileName = './sampleData/example1.xls';
$sheetname = 'Data Sheet #2';

/**  Create a new Reader of the type defined in $inputFileType  **/
$reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader($inputFileType);
/**  Advise the Reader of which WorkSheets we want to load  **/
$reader->setLoadSheetsOnly($sheetname);
/**  Load $inputFileName to a Spreadsheet Object  **/
$spreadsheet = $reader->load($inputFileName);

See samples/Reader/07_Simple_file_reader_loading_a_single_named_worksheet.php for a working example of this code.

If you want to read more than one sheet, you can pass a list of sheet names as an array parameter to the setLoadSheetsOnly() method.

$inputFileType = 'Xls';
$inputFileName = './sampleData/example1.xls';
$sheetnames = ['Data Sheet #1','Data Sheet #3'];

/**  Create a new Reader of the type defined in $inputFileType  **/
$reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader($inputFileType);
/**  Advise the Reader of which WorkSheets we want to load  **/
$reader->setLoadSheetsOnly($sheetnames);
/**  Load $inputFileName to a Spreadsheet Object  **/
$spreadsheet = $reader->load($inputFileName);

See samples/Reader/08_Simple_file_reader_loading_several_named_worksheets.php for a working example of this code.

To reset this option to its default value, you can call the setLoadAllSheets() method.

$inputFileType = 'Xls';
$inputFileName = './sampleData/example1.xls';

/**  Create a new Reader of the type defined in $inputFileType  **/
$reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader($inputFileType);
/**  Advise the Reader to load all Worksheets  **/
$reader->setLoadAllSheets();
/**  Load $inputFileName to a Spreadsheet Object  **/
$spreadsheet = $reader->load($inputFileName);

See samples/Reader/06_Simple_file_reader_loading_all_worksheets.php for a working example of this code.

Reading only named worksheets from files applies to readers:

Reader Yes/No Reader Yes/No Reader Yes/No
Xlsx Yes Xls Yes Xml Yes
Ods Yes Slk No Gnumeric Yes
CSV No Html No

Reading Only Specific Columns and Rows from Files (Read Filter)

If you're only interested in reading part of a worksheet, you can write a filter class that identifies whether the loader should read an individual cell. The read filter must implement the \PhpOffice\PhpSpreadsheet\Reader\IReadFilter interface, and contain a readCell() method that accepts parameters $column, $row and $worksheetName, and returns a boolean true or false indicating whether the cell identified by these parameters should be read or not.

$inputFileType = 'Xls';
$inputFileName = './sampleData/example1.xls';
$sheetname = 'Data Sheet #3';

/**  Define a Read Filter class implementing \PhpOffice\PhpSpreadsheet\Reader\IReadFilter  */
class MyReadFilter implements \PhpOffice\PhpSpreadsheet\Reader\IReadFilter
{
    public function readCell($column, $row, $worksheetName = '') {
        //  Read rows 1 to 7 and columns A to E only
        if ($row >= 1 && $row <= 7) {
            if (in_array($column,range('A','E'))) {
                return true;
            }
        }
        return false;
    }
}

/**  Create an Instance of our Read Filter  **/
$filterSubset = new MyReadFilter();

/**  Create a new Reader of the type defined in $inputFileType  **/
$reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader($inputFileType);
/**  Tell the Reader that we want to use the Read Filter  **/
$reader->setReadFilter($filterSubset);
/**  Load only the rows and columns that match our filter to Spreadsheet  **/
$spreadsheet = $reader->load($inputFileName);

See samples/Reader/09_Simple_file_reader_using_a_read_filter.php for a working example of this code.

This example isn't particularly useful as it can only be used in very specific circumstances (when you only want cells in the range A1:E7 of a worksheet. A more generic read filter might be more useful:

/**  Define a Read Filter class implementing \PhpOffice\PhpSpreadsheet\Reader\IReadFilter  */
class MyReadFilter implements \PhpOffice\PhpSpreadsheet\Reader\IReadFilter
{
    private $startRow = 0;
    private $endRow   = 0;
    private $columns  = [];

    /**  Get the list of rows and columns to read  */
    public function __construct($startRow, $endRow, $columns) {
        $this->startRow = $startRow;
        $this->endRow   = $endRow;
        $this->columns  = $columns;
    }

    public function readCell($column, $row, $worksheetName = '') {
        //  Only read the rows and columns that were configured
        if ($row >= $this->startRow && $row <= $this->endRow) {
            if (in_array($column,$this->columns)) {
                return true;
            }
        }
        return false;
    }
}

/**  Create an Instance of our Read Filter, passing in the cell range  **/
$filterSubset = new MyReadFilter(9,15,range('G','K'));

See samples/Reader/10_Simple_file_reader_using_a_configurable_read_filter.php for a working example of this code.

By allowing you to read and process large workbooks in "chunks", this is particularly useful for saving memory: for example, when transferring data from an Excel worksheet to a database, an example of this usage.

$inputFileType = 'Xls';
$inputFileName = './sampleData/example2.xls';

/**  Define a Read Filter class implementing \PhpOffice\PhpSpreadsheet\Reader\IReadFilter  */
class ChunkReadFilter implements \PhpOffice\PhpSpreadsheet\Reader\IReadFilter
{
    private $startRow = 0;
    private $endRow   = 0;

    /**  Set the list of rows that we want to read  */
    public function setRows($startRow, $chunkSize) {
        $this->startRow = $startRow;
        $this->endRow   = $startRow + $chunkSize;
    }

    public function readCell($column, $row, $worksheetName = '') {
        //  Only read the heading row, and the configured rows
        if (($row == 1) || ($row >= $this->startRow && $row < $this->endRow)) {
            return true;
        }
        return false;
    }
}

/**  Create a new Reader of the type defined in $inputFileType  **/
$reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader($inputFileType);

/**  Define how many rows we want to read for each "chunk"  **/
$chunkSize = 2048;
/**  Create a new Instance of our Read Filter  **/
$chunkFilter = new ChunkReadFilter();

/**  Tell the Reader that we want to use the Read Filter  **/
$reader->setReadFilter($chunkFilter);

/**  Loop to read our worksheet in "chunk size" blocks  **/
for ($startRow = 2; $startRow <= 65536; $startRow += $chunkSize) {
    /**  Tell the Read Filter which rows we want this iteration  **/
    $chunkFilter->setRows($startRow,$chunkSize);
    /**  Load only the rows that match our filter  **/
    $spreadsheet = $reader->load($inputFileName);
    //    Do some processing here
}

See samples/Reader/12_Reading_a_workbook_in_chunks_using_a_configurable_read_filter_ for a working example of this code.

Using read filters applies to:

Reader Yes/No Reader Yes/No Reader Yes/No
Xlsx Yes Xls Yes Xml Yes
Ods Yes Slk No Gnumeric Yes
CSV Yes Html No

Merging Multiple Files into a Single Spreadsheet Object

While you can use the setLoadSheetsOnly() method to limit the number of worksheets read from a workbook file, some readers also allow you to combine multiple individual "worksheets" from different files into a single Spreadsheet object, where each individual file becomes a single worksheet in that workbook. For each file you read, you need to use the setSheetIndex() method to indicate which worksheet index it should be loaded into for the $reader, then use the loadIntoExisting() method rather than the load() method to actually read the file into that worksheet.

$inputFileType = 'Csv';
$inputFileNames = [
    './sampleData/example1.csv',
    './sampleData/example2.csv'
    './sampleData/example3.csv'
];

/**  Create a new Reader of the type defined in $inputFileType  **/
$reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader($inputFileType);

/**  Extract the first named file from the array list  **/
$inputFileName = array_shift($inputFileNames);
/**  Load the initial file to the first worksheet in a `Spreadsheet` Object  **/
$spreadsheet = $reader->load($inputFileName);
/**  Set the worksheet title (to the filename that we've loaded)  **/
$spreadsheet->getActiveSheet()
    ->setTitle(pathinfo($inputFileName,PATHINFO_BASENAME));

/**  Loop through all the remaining files in the list  **/
foreach($inputFileNames as $sheet => $inputFileName) {
    /**  Increment the worksheet index pointer for the Reader  **/
    $reader->setSheetIndex($sheet+1);
    /**  Load the current file into a new worksheet in Spreadsheet  **/
    $reader->loadIntoExisting($inputFileName,$spreadsheet);
    /**  Set the worksheet title (to the filename that we've loaded)  **/
    $spreadsheet->getActiveSheet()
        ->setTitle(pathinfo($inputFileName,PATHINFO_BASENAME));
}

See samples/Reader/13_Simple_file_reader_for_multiple_CSV_files.php for a working example of this code.

Please note that using the same worksheet index for multiple worksheets won't append files to the same worksheet, but will overwrite the previously loaded results. You cannot load multiple CSV files into the same worksheet.

Merging multiple files into a single spreadsheet object applies to:

Reader Yes/No Reader Yes/No Reader Yes/No
Xlsx No Xls No Xml No
Ods No Slk Yes Gnumeric No
CSV Yes Html No

Combining Read Filters with setSheetIndex() for Large CSV Files

Xls BIFF .xls files are limited to 65536 rows per worksheet, while Xlsx Microsoft Office Open XML SpreadsheetML .xlsx files are limited to 1,048,576 rows per worksheet; but CSV files are not limited by available disk space. This means we often can't read all rows from an extremely large CSV file and save it as Xls or Xlsx files. However, by using a "read filter" to read the CSV file in "chunks" (using our ChunkReadFilter class defined in the previous section) and the setSheetIndex() method of $reader, we can split the CSV file into several separate worksheets.

$inputFileType = 'Csv';
$inputFileName = './sampleData/example2.csv';

echo 'Loading file ',pathinfo($inputFileName,PATHINFO_BASENAME),' using IOFactory with a defined reader type of ',$inputFileType,'<br />';
/**  Create a new Reader of the type defined in $inputFileType  **/
$reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader($inputFileType);

/**  Define how many rows we want to read for each "chunk"  **/
$chunkSize = 65530;
/**  Create a new Instance of our Read Filter  **/
$chunkFilter = new ChunkReadFilter();

/**  Tell the Reader that we want to use the Read Filter  **/
/**    and that we want to store it in contiguous rows/columns  **/

$reader->setReadFilter($chunkFilter)
    ->setContiguous(true);

/**  Instantiate a new Spreadsheet object manually  **/
$spreadsheet = new \PhpOffice\PhpSpreadsheet\Spreadsheet();

/**  Set a sheet index  **/
$sheet = 0;
/**  Loop to read our worksheet in "chunk size" blocks  **/
/**  $startRow is set to 2 initially because we always read the headings in row #1  **/
for ($startRow = 2; $startRow <= 1000000; $startRow += $chunkSize) {
    /**  Tell the Read Filter which rows we want to read this loop  **/
    $chunkFilter->setRows($startRow,$chunkSize);

    /**  Increment the worksheet index pointer for the Reader  **/
    $reader->setSheetIndex($sheet);
    /**  Load only the rows that match our filter into a new worksheet  **/
    $reader->loadIntoExisting($inputFileName,$spreadsheet);
    /**  Set the worksheet title for the sheet that we've just loaded)  **/
    /**    and increment the sheet index as well  **/
    $spreadsheet->getActiveSheet()->setTitle('Country Data #'.(++$sheet));
}

See samples/Reader/14_Reading_a_large_CSV_file_in_chunks_to_split_across_multiple_worksheets.php for a working example of this code.

This code will read 65,530 rows at a time from the CSV file we're loading, and store each "chunk" in a new worksheet.

The setContiguous() method of the reader is important here. It only applies when using a "read filter", and identifies whether cells should be stored in their position in the CSV file, or relative to the filter.

For example, if the filter returns true for cells in the range B2:C3, setting setContiguous to false (the default), these will be loaded as B2:C3 into the Spreadsheet object. But setting setContiguous to true, they will be loaded as A1:B2.

Splitting a single loaded file across multiple worksheets applies to:

Reader Yes/No Reader Yes/No Reader Yes/No
Xlsx No Xls No Xml No
Ods No Slk No Gnumeric No
CSV Yes Html No

Pipe or Tab Separated Value Files

The CSV loader will attempt to auto-detect the delimiter used in the file. If auto-detection isn't possible, it will default to comma. If this doesn't suit your use case, you can manually specify the delimiter using the setDelimiter() method.

$inputFileType = 'Csv';
$inputFileName = './sampleData/example1.tsv';

/**  Create a new Reader of the type defined in $inputFileType  **/
$reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader($inputFileType);
/**  Set the delimiter to a TAB character  **/
$reader->setDelimiter("\t");
//    $reader->setDelimiter('|');

/**  Load the file to a Spreadsheet Object  **/
$spreadsheet = $reader->load($inputFileName);

See samples/Reader/15_Simple_file_reader_for_tab_separated_value_file_using_the_Advanced_Value_Binder.php for a working example of this code.

In addition to the delimiter, you can set other properties for data loading using the following methods:

Method Default
setEnclosure() "
setInputEncoding() UTF-8

Setting CSV delimiters applies to:

Reader Yes/No Reader Yes/No Reader Yes/No
Xlsx No Xls No Xml No
Ods No Slk No Gnumeric No
CSV Yes Html No

Brief Introduction to Advanced Value Binder

When loading data from files that don't contain format information (such as CSV files), the data will be read as strings or numbers (floats or integers). This means PhpSpreadsheet won't automatically recognize dates/times (such as 16-Apr-2009 or 13:30), booleans (true or false), percentages (75%), hyperlinks (https://www.example.com) as anything other than simple strings. However, additional processing can be applied during loading using a Value Binder.

A Value Binder is a class that implements the \PhpOffice\PhpSpreadsheet\Cell\IValueBinder interface. It must contain a bindValue() method that accepts a \PhpOffice\PhpSpreadsheet\Cell\Cell and a value as parameters, and returns a boolean true or false indicating whether the workbook cell has been populated with that value. The Advanced Value Binder implements such a class: among other tests, it identifies strings containing "TRUE" or "FALSE" (based on locale) and sets them as booleans; or numbers in scientific format (such as "1.234e-5") and covnerts them to floats; or dates and times, converting them to Excel timestamp values – before storing the value in the cell object. It also sets formatting for strings identified as dates, times or percentages. It can be easily extended to provide additional processing (including text or cell formatting) when it encounters hyperlinks or HTML markup in CSV files.

Thus, using a Value Binder can provide greater flexibility in the loader logic when reading unformatted text files.

/**  Tell PhpSpreadsheet that we want to use the Advanced Value Binder  **/
\PhpOffice\PhpSpreadsheet\Cell\Cell::setValueBinder( new \PhpOffice\PhpSpreadsheet\Cell\AdvancedValueBinder() );

$inputFileType = 'Csv';
$inputFileName = './sampleData/example1.tsv';

$reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader($inputFileType);
$reader->setDelimiter("\t");
$spreadsheet = $reader->load($inputFileName);

See samples/Reader/15_Simple_file_reader_for_tab_separated_value_file_using_the_Advanced_Value_Binder.php for a working example of this code.

Using Value Binders for loading applies to:

Reader Yes/No Reader Yes/No Reader Yes/No
Xlsx No Xls No Xml No
Ods No Slk No Gnumeric No
CSV Yes Html Yes

Error Handling

Of course, you should also always implement some error handling for your script. PhpSpreadsheet throws exceptions, so you can wrap all code accessing library methods in a Try/Catch block to catch any problems encountered, and handle them appropriately.

PhpSpreadsheet readers will throw a \PhpOffice\PhpSpreadsheet\Reader\Exception.

$inputFileName = './sampleData/example-1.xls';

try {
    /** Load $inputFileName to a Spreadsheet Object  **/
    $spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load($inputFileName);
} catch(\PhpOffice\PhpSpreadsheet\Reader\Exception $e) {
    die('Error loading file: '.$e->getMessage());
}

See samples/Reader/16_Handling_loader_exceptions_using_TryCatch.php for a working example of this code.

Helper Methods

You can retrieve a list of worksheet names contained in a file without loading the entire file using the Reader's listWorksheetNames() method. Similarly, a listWorksheetInfo() method will retrieve the dimensions of worksheets in the file without loading and parsing the entire file.

listWorksheetNames

The listWorksheetNames() method returns a simple array listing each worksheet name in the workbook:

$reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader($inputFileType);

$worksheetNames = $reader->listWorksheetNames($inputFileName);

echo '<h3>Worksheet Names</h3>';
echo '<ol>';
foreach ($worksheetNames as $worksheetName) {
    echo '<li>', $worksheetName, '</li>';
}
echo '</ol>';

See samples/Reader/18_Reading_list_of_worksheets_without_loading_entire_file.php for a working example of this code.

listWorksheetInfo

The listWorksheetInfo() method returns a nested array, with each entry listing the name and dimensions of a worksheet:

$reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader($inputFileType);

$worksheetData = $reader->listWorksheetInfo($inputFileName);

echo '<h3>Worksheet Information</h3>';
echo '<ol>';
foreach ($worksheetData as $worksheet) {
    echo '<li>', $worksheet['worksheetName'], '<br />';
    echo 'Rows: ', $worksheet['totalRows'],
         ' Columns: ', $worksheet['totalColumns'], '<br />';
    echo 'Cell Range: A1:',
    $worksheet['lastColumnLetter'], $worksheet['totalRows'];
    echo '</li>';
}
echo '</ol>';

See samples/Reader/19_Reading_worksheet_information_without_loading_entire_file.php for a working example of this code.

Tags: PhpSpreadsheet Excel CSV File I/O Spreadsheet

Posted on Sat, 27 Jun 2026 16:36:57 +0000 by bundred