Read excel files with php

Security

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

  • Disclosure whether a file is existent
  • Server Side Request Forgery
  • Command Execution (depending on the installed PHP wrappers)

To prevent this, by default every XML-based Reader looks for XML
entities declared inside the DOCTYPE and if any is found an exception
is raised.

Read more about of XXE injection.

Loading a Spreadsheet File

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

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

/** Load $inputFileName to a Spreadsheet Object  **/
$spreadsheet = PhpOfficePhpSpreadsheetIOFactory::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 will test the file before actually executing the
load: so if (for example) the file is actually a CSV file or contains
HTML markup, but that has been given a .xls extension (quite a common
practise), it will reject the Xls loader that it would normally use for
a .xls file; and test the file using the other loaders until it finds
the appropriate loader, and then use that to read the file.

If you know that this is an xls file, but don’t know whether it is a
genuine BIFF-format Excel or Html markup with an xls extension, you can
limit the loader to check only those two possibilities by passing in an
array of Readers to test against.

$inputFileName = './sampleData/example1.xls';
$testAgainstFormats = [
    PhpOfficePhpSpreadsheetIOFactory::READER_XLS,
    PhpOfficePhpSpreadsheetIOFactory::READER_HTML,
];

/** Load $inputFileName to a Spreadsheet Object  **/
$spreadsheet = PhpOfficePhpSpreadsheetIOFactory::load($inputFileName, 0, $testAgainstFormats);

While easy to implement in your code, and you don’t need to worry about
the file type; this isn’t the most efficient method to load a file; 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 that 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 to a Spreadsheet object. It is
possible to instantiate the reader objects for each of the different
supported filetype by name. However, you may get unpredictable results
if the file isn’t of the right type (e.g. it is a CSV with an extension
of .xls), although this type of exception should normally be trapped.

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

/** Create a new Xls Reader  **/
$reader = new PhpOfficePhpSpreadsheetReaderXls();
//    $reader = new PhpOfficePhpSpreadsheetReaderXlsx();
//    $reader = new PhpOfficePhpSpreadsheetReaderXml();
//    $reader = new PhpOfficePhpSpreadsheetReaderOds();
//    $reader = new PhpOfficePhpSpreadsheetReaderSlk();
//    $reader = new PhpOfficePhpSpreadsheetReaderGnumeric();
//    $reader = new PhpOfficePhpSpreadsheetReaderCsv();
/** 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 that you want instantiating.

$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 = PhpOfficePhpSpreadsheetIOFactory::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 uncertain of the filetype, you can use the IOFactory::identify()
method to identify the reader that you need, before using the
createReader() method to instantiate the reader object.

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

/**  Identify the type of $inputFileName  **/
$inputFileType = PhpOfficePhpSpreadsheetIOFactory::identify($inputFileName);
/**  Create a new Reader of the type that has been identified  **/
$reader = PhpOfficePhpSpreadsheetIOFactory::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.

As with the IOFactory load() method, you can also pass an array of formats
for the identify() method to check against if you know that it will only
be in a subset of the possible formats that PhpSpreadsheet supports.

$inputFileName = './sampleData/example1.xls';
$testAgainstFormats = [
    PhpOfficePhpSpreadsheetIOFactory::READER_XLS,
    PhpOfficePhpSpreadsheetIOFactory::READER_HTML,
];

/**  Identify the type of $inputFileName  **/
$inputFileType = PhpOfficePhpSpreadsheetIOFactory::identify($inputFileName, $testAgainstFormats);

You can also use this to confirm that a file is what it claims to be:

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

try {
    /**  Verify that $inputFileName really is an Xls file **/
    $inputFileType = PhpOfficePhpSpreadsheetIOFactory::identify($inputFileName, [PhpOfficePhpSpreadsheetIOFactory::READER_XLS]);
} catch (PhpOfficePhpSpreadsheetReaderException $e) {
    // File isn't actually an Xls file, even though it has an xls extension 
}

Spreadsheet Reader Options

Once you have created a reader object for the workbook that you want to
load, you have the opportunity to set additional options before
executing the load() method.

Reading Only Data from a Spreadsheet File

If you’re only interested in the cell values in a workbook, but don’t
need any of the cell formatting information, then you can set the reader
to read only the data values and any formulae from each cell using the
setReadDataOnly() method.

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

/**  Create a new Reader of the type defined in $inputFileType  **/
$reader = PhpOfficePhpSpreadsheetIOFactory::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 is important to note that most Workbooks (and PhpSpreadsheet) store dates
and times as simple numeric values: they can only be distinguished from
other numeric values by the format mask that is applied to that cell.
When setting read data only to true, PhpSpreadsheet doesn’t read the
cell format masks, so it is not possible to differentiate between
dates/times and numbers.

The Gnumeric loader has been written to read the format masks for date
values even when read data only has been set to true, so it can
differentiate between dates/times and numbers; but this change hasn’t
yet been implemented for the other readers.

Reading Only Data from a Spreadsheet File applies to Readers:

Reader Y/N Reader Y/N Reader Y/N
Xlsx YES Xls YES Xml YES
Ods YES SYLK NO Gnumeric YES
CSV NO HTML NO

Reading Only Named WorkSheets from a File

If your workbook contains a number of worksheets, but you are only
interested in reading some of those, then you can use the
setLoadSheetsOnly() method to identify those sheets you are interested
in reading.

To read a single sheet, you can pass that 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 = PhpOfficePhpSpreadsheetIOFactory::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 just a single 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 = PhpOfficePhpSpreadsheetIOFactory::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 the default, you can call the setLoadAllSheets()
method.

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

/**  Create a new Reader of the type defined in $inputFileType  **/
$reader = PhpOfficePhpSpreadsheetIOFactory::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 a File applies to Readers:

Reader Y/N Reader Y/N Reader Y/N
Xlsx YES Xls YES Xml YES
Ods YES SYLK NO Gnumeric YES
CSV NO HTML NO

Reading Only Specific Columns and Rows from a File (Read Filters)

If you are only interested in reading part of a worksheet, then you can
write a filter class that identifies whether or not individual cells
should be read by the loader. A read filter must implement the
PhpOfficePhpSpreadsheetReaderIReadFilter interface, and contain a
readCell() method that accepts arguments of $column, $row and
$worksheetName, and return a boolean true or false that indicates
whether a workbook cell identified by those arguments should be read or
not.

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

/**  Define a Read Filter class implementing PhpOfficePhpSpreadsheetReaderIReadFilter  */
class MyReadFilter implements PhpOfficePhpSpreadsheetReaderIReadFilter
{
    public function readCell($columnAddress, $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 = PhpOfficePhpSpreadsheetIOFactory::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 is not particularly useful, because it can only be used in
a very specific circumstance (when you only want cells in the range
A1:E7 from your worksheet. A generic Read Filter would probably be more
useful:

/**  Define a Read Filter class implementing PhpOfficePhpSpreadsheetReaderIReadFilter  */
class MyReadFilter implements PhpOfficePhpSpreadsheetReaderIReadFilter
{
    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($columnAddress, $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.

This can be particularly useful for conserving memory, by allowing you
to read and process a large workbook in «chunks»: an example of this
usage might be when transferring data from an Excel worksheet to a
database.

Read Filtering does not renumber cell rows and columns. If you filter to read only rows 100-200, cells that you read will still be numbered A100-A200, not A1-A101. Cells A1-A99 will not be loaded, but if you then try to call getCell() for a cell outside your loaded range, then PHPSpreadsheet will create a new cell with a null value.

Methods such as toArray() assume that all cells in a spreadsheet has been loaded from A1, so will return null values for rows and columns that fall outside your filter range: it is recommended that you keep track of the range that your filter has requested, and use rangeToArray() instead.

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

/**  Define a Read Filter class implementing PhpOfficePhpSpreadsheetReaderIReadFilter  */
class ChunkReadFilter implements PhpOfficePhpSpreadsheetReaderIReadFilter
{
    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($columnAddress, $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 = PhpOfficePhpSpreadsheetIOFactory::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 Y/N Reader Y/N Reader Y/N
Xlsx YES Xls YES Xml YES
Ods YES SYLK NO Gnumeric YES
CSV YES HTML NO

Combining Multiple Files into a Single Spreadsheet Object

While you can limit the number of worksheets that are read from a
workbook file using the setLoadSheetsOnly() method, certain readers also
allow you to combine several individual «sheets» from different files
into a single Spreadsheet object, where each individual file is a
single worksheet within that workbook. For each file that you read, you
need to indicate which worksheet index it should be loaded into using
the setSheetIndex() method of 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 = PhpOfficePhpSpreadsheetIOFactory::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.

Note that using the same sheet index for multiple sheets won’t append
files into the same sheet, but overwrite the results of the previous
load. You cannot load multiple CSV files into the same worksheet.

Combining Multiple Files into a Single Spreadsheet Object applies to:

Reader Y/N Reader Y/N Reader Y/N
Xlsx NO Xls NO Xml NO
Ods NO SYLK YES Gnumeric NO
CSV YES HTML NO

Combining Read Filters with the setSheetIndex() method to split a large CSV file across multiple Worksheets

An Xls BIFF .xls file is limited to 65536 rows in a worksheet, while the
Xlsx Microsoft Office Open XML SpreadsheetML .xlsx file is limited to
1,048,576 rows in a worksheet; but a CSV file is not limited other than
by available disk space. This means that we wouldn’t ordinarily be able
to read all the rows from a very large CSV file that exceeded those
limits, and save it as an Xls or Xlsx file. However, by using Read
Filters to read the CSV file in «chunks» (using the ChunkReadFilter
Class that we defined in the above section,
and the setSheetIndex() method of the $reader, we can split the CSV
file across several individual 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 = PhpOfficePhpSpreadsheetIOFactory::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 PhpOfficePhpSpreadsheetSpreadsheet();

/**  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 justloaded)  **/
    /**    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 that we’re
loading, and store each «chunk» in a new worksheet.

The setContiguous() method for the Reader is important here. It is
applicable only when working with a Read Filter, and identifies whether
or not the cells should be stored by their position within the CSV file,
or their position relative to the filter.

For example, if the filter returned true for cells in the range B2:C3,
then with setContiguous set to false (the default) these would be loaded
as B2:C3 in the Spreadsheet object; but with setContiguous set to
true, they would be loaded as A1:B2.

Splitting a single loaded file across multiple worksheets applies to:

Reader Y/N Reader Y/N Reader Y/N
Xlsx NO Xls NO Xml NO
Ods NO SYLK NO Gnumeric NO
CSV YES HTML NO

Pipe or Tab Separated Value Files

The CSV loader will attempt to auto-detect the separator used in the file. If it
cannot auto-detect, it will default to the comma. If this does not fit your
use-case, you can manually specify a separator by using the setDelimiter()
method.

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

/**  Create a new Reader of the type defined in $inputFileType  **/
$reader = PhpOfficePhpSpreadsheetIOFactory::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 also use the following methods to
set other attributes for the data load:

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

Setting CSV delimiter applies to:

Reader Y/N Reader Y/N Reader Y/N
Xlsx NO Xls NO Xml NO
Ods NO SYLK NO Gnumeric NO
CSV YES HTML NO

Reading formatted Numbers from a CSV File

Unfortunately, numbers in a CSV file may be formatted as strings.
If that number is a simple integer or float (with a decimal . separator) without any thousands separator, then it will be treated as a number.
However, if the value has a thousands separator (e.g. 12,345), or a decimal separator that isn’t a . (e.g. 123,45 for a European locale), then it will be loaded as a string with that formatting.
If you want the Csv Reader to convert that value to a numeric when it loads the file, the you need to tell it to do so. The castFormattedNumberToNumeric() lets you do this.

(Assuming that our server is configured with German locale settings: otherwise it may be necessary to call setlocale() before loading the file.)

$inputFileType = 'Csv';
$inputFileName = './sampleData/example1.de.csv';

/** It may be necessary to call setlocale() first if this is not your default locale  */
// setlocale(LC_ALL, 'de_DE.UTF-8', 'deu_deu');

/**  Create a new Reader of the type defined in $inputFileType  **/
$reader = PhpOfficePhpSpreadsheetIOFactory::createReader($inputFileType);
/**  Enable loading numeric values formatted with German , decimal separator and . thousands separator  **/
$reader->castFormattedNumberToNumeric(true);

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

This will attempt to load those formatted numeric values as numbers, based on the server’s locale settings.

If you want to load those values as numbers, but also to retain the formatting as a number format mask, then you can pass a boolean true as a second argument to the castFormattedNumberToNumeric() method to tell the Reader to identify the format masking to use for that value. This option does have an arbitrary limit of 6 decimal places.

If your Csv file includes other formats for numbers (currencies, scientific format, etc); then you should probably also use the Advanced Value Binder to handle these cases.

Applies to:

Reader Y/N Reader Y/N Reader Y/N
Xlsx NO Xls NO Xml NO
Ods NO SYLK NO Gnumeric NO
CSV YES HTML NO

A Brief Word about the Advanced Value Binder

When loading data from a file that contains no formatting information,
such as a CSV file, then data is read either as strings or numbers
(float or integer). This means that PhpSpreadsheet does not
automatically recognise dates/times (such as 16-Apr-2009 or 13:30),
booleans (true or false), percentages (75%), hyperlinks
(https://www.example.com), etc as anything other than simple strings.
However, you can apply additional processing that is executed against
these values during the load process within a Value Binder.

A Value Binder is a class that implement the
PhpOfficePhpSpreadsheetCellIValueBinder interface. It must contain a
bindValue() method that accepts a PhpOfficePhpSpreadsheetCellCell and a
value as arguments, and return a boolean true or false that indicates
whether the workbook cell has been populated with the value or not. The
Advanced Value Binder implements such a class: amongst other tests, it
identifies a string comprising «TRUE» or «FALSE» (based on locale
settings) and sets it to a boolean; or a number in scientific format
(e.g. «1.234e-5») and converts it to a float; or dates and times,
converting them to their Excel timestamp value – before storing the
value in the cell object. It also sets formatting for strings that are
identified as dates, times or percentages. It could easily be extended
to provide additional handling (including text or cell formatting) when
it encountered a hyperlink, or HTML markup within a CSV file.

So using a Value Binder allows a great deal more flexibility in the
loader logic when reading unformatted text files.

/**  Tell PhpSpreadsheet that we want to use the Advanced Value Binder  **/
PhpOfficePhpSpreadsheetCellCell::setValueBinder( new PhpOfficePhpSpreadsheetCellAdvancedValueBinder() );

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

$reader = PhpOfficePhpSpreadsheetIOFactory::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.

Loading using a Value Binder applies to:

Reader Y/N Reader Y/N Reader Y/N
Xlsx NO Xls NO Xml NO
Ods NO SYLK NO Gnumeric NO
CSV YES HTML YES

Error Handling

Of course, you should always apply some error handling to your scripts
as well. PhpSpreadsheet throws exceptions, so you can wrap all your code
that accesses the library methods within Try/Catch blocks to trap for
any problems that are encountered, and deal with them in an appropriate
manner.

The PhpSpreadsheet Readers throw a
PhpOfficePhpSpreadsheetReaderException.

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

try {
    /** Load $inputFileName to a Spreadsheet Object  **/
    $spreadsheet = PhpOfficePhpSpreadsheetIOFactory::load($inputFileName);
} catch(PhpOfficePhpSpreadsheetReaderException $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 whole file by using the Reader’s listWorksheetNames()
method; similarly, a listWorksheetInfo() method will retrieve the
dimensions of worksheet in a file without needing to load and parse the
whole file.

listWorksheetNames

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

$reader = PhpOfficePhpSpreadsheetIOFactory::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 for a worksheet:

$reader = PhpOfficePhpSpreadsheetIOFactory::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.

В статье представлены различные PHP-расширения для чтения файлов XLS, XLSX, описаны их плюсы и минусы, а также примеры чтения.

1

PHPExcel

https://github.com/PHPOffice/PHPExcel

Огромная библиотека читает и формирует фалы xls, xlsx, csv.

  • Для файлов xlsx потребует расширение ZipArchive.
  • Потребляет много памяти.

Пример чтения файла в массив:

require_once __DIR__ . '/PHPExcel-1.8/Classes/PHPExcel/IOFactory.php';

// Файл xlsx
$xls = PHPExcel_IOFactory::load(__DIR__ . '/test.xlsx');

// Первый лист
$xls->setActiveSheetIndex(0);
$sheet = $xls->getActiveSheet();

foreach ($sheet->toArray() as $row) {
   print_r($row);
}

PHP

2

SimpleXLSX

https://www.phpclasses.org/package/6279-PHP-Parse-and-retrieve-data-from-Excel-XLS-files.html
simple-xlsx.zip (2017-09-25)

Читает только файлы xlsx.

  • Менее прожорлив к памяти.
  • Не всегда может прочитать файл, например файл сформированный PHPExcel.
require_once __DIR__ . '/simple-xlsx/simplexlsx.class.php'; 

// Файл xlsx
$xlsx = new SimpleXLSX(__DIR__ . '/test.xlsx');

// Первый лист
$sheet = $xlsx->rows(1);

foreach ($sheet as $row) {
   print_r($row);
}

PHP

3

PHP-ExcelReader

https://sourceforge.net/projects/phpexcelreader/
phpExcelReader.zip (исправленный)

  • Прочтёт только XLS файлы.
  • Есть проблемы с кодировкой.
require_once __DIR__ . '/phpExcelReader/Excel/reader.php';   

$data = new Spreadsheet_Excel_Reader();
$data->setOutputEncoding('UTF-8');

// Файл xls
$data->read(__DIR__ . '/test.xls');

// Первый лист
$sheet = $data->sheets[0]['cells'];

foreach ($sheet as $row) {
	print_r($row);
}

PHP

4

PHP-Excel-Reader

https://code.google.com/archive/p/php-excel-reader/
php-excel-reader.zip (2.21)

Форк библиотеки «PHP Excel Reader» с SourceForge предназначенный для вывода таблицы в HTML.

Например файл example.xls выведет следующим образом:

<style>
table.excel {
	border: 1px solid #CCCCCC;
	border-collapse:collapse;
	font-family:sans-serif;
	font-size:12px;
	margin: 0 auto;
}
table.excel thead th, table.excel tbody th {
	border: 1px solid #CCCCCC;
	text-align: center;
	vertical-align:bottom;
}
table.excel tbody th {
	text-align:center;
	width:20px;
}
table.excel tbody td {
	vertical-align:bottom;
}
table.excel tbody td {
	padding: 0 3px;
	border: 1px solid #EEEEEE;
}
</style>

<?php
require_once __DIR__ . '/php-excel-reader/excel_reader2.php';   
$data = new Spreadsheet_Excel_Reader(__DIR__ . '/example.xls');
echo $data->dump(true, true);
?>

HTML

Также у библиотеки есть методы для получения формата и содержания каждой ячейки по отдельности.

5

Nuovo Spreadsheet-Reader

https://github.com/nuovo/spreadsheet-reader
spreadsheet-reader.zip

Читает файлы XLSX, XLS, CSV и OpenOffice ods. Для чтения XLS используется предыдущая библиотека php-excel-reader.

require_once __DIR__ . '/spreadsheet-reader/php-excel-reader/excel_reader2.php';    
require_once __DIR__ . '/spreadsheet-reader/SpreadsheetReader.php';    

// Файл xlsx, xls, csv, ods.
$Reader = new SpreadsheetReader(__DIR__ . '/test.xlsx');

// Номер листа.
$Reader -> ChangeSheet(0);

foreach ($Reader as $Row) {
	print_r($Row);
}

PHP

6

PHP-Spreadsheetreader

https://code.google.com/archive/p/php-spreadsheetreader/
SpreadsheetReader.rar

Откроет только файлы в формате XML Excel 2004.

$file = __DIR__ . '/test.xml';

require_once __DIR__ . '/SpreadsheetReader/SpreadsheetReader.php';    
$reader = new SpreadsheetReader;

// Файл xml
$sheets = $reader->read(__DIR__ . '/test.xml');

// Выводим Первый лист
foreach ($sheets[0] as $row) {
   print_r($row);
}

PHP

При построении различных сервисов, иногда бывает необходимость прочитать xlsx документ и с данными, которые в нем содержатся что-то сделать, записать в базу, вывести на страницу или переформатировать и снова записать в файл, вариантов много. В предыдущей статье, был описан процесс создания excel документов при помощи php, почитать можно здесь В этой статье будет использоваться тот же пакет phpoffice/phpspreadsheet, для работы с документами excel.

Структура проекта

├── Файл index.php
├── Файл composer.json
├── Обрабатываемый файл xlsx

Шаг 1 — установка пакета phpoffice/phpspreadsheet

Данная статья написана, с учетом того, что composer у Вас установлен, поэтому переходим к созданию файла composer.json, его содержание:

{
    "require": {
      "phpoffice/phpspreadsheet": "^1.18"
    }
}

В этой же директории запускаем команду composer require

После успешного выполнения этой команды, произойдет установка необходимых пакетов, с зависимостями, структура немного изменится, будет такой:

├── Файл index.php
├── Файл composer.json
├── Файл composer.lock
├── Обрабатываемый файл xlsx
├── Директория vendor
   └── Директории с файлами пакетов

Файл xlsx у меня с таким содержимым:

файл xlsx

В самом простом примере прочитаем файл xlsx в массив и выведем функцией print_r, для этого необходимо написать index.php, код будет такой:

<?php
set_include_path(__DIR__);

require './vendor/autoload.php';


use PhpOfficePhpSpreadsheetReaderXlsx;

$inputFileName = __DIR__ . '/file32342.xlsx';

$reader = new Xlsx();
$spreadsheet = $reader->load($inputFileName);

$sheetData = $spreadsheet->getActiveSheet()->toArray(null, true, true, true);


echo '<pre>';
print_r($sheetData);
echo '</pre>';

В результате выполнения этого кода, увидим вот такой распечатанный массив:

Array
(
    [1] => Array
        (
            [A] => Значение А1
            [B] => Значение В1
            [C] => Значение С1
            [D] => Значение D1
            [E] => Значение E1
            [F] => Значение F1
            [G] => Значение G1
            [H] => Значение H1
            [I] => Значение I1
            [J] => Значение J1
            [K] => Значение K1
            [L] => Значение L1
            [M] => Значение M1
        )

    [2] => Array
        (
            [A] => Значение А2
            [B] => Значение В2
            [C] => Значение С2
            [D] => Значение D2
            [E] => Значение E2
            [F] => Значение F2
            [G] => Значение G2
            [H] => Значение H2
            [I] => Значение I2
            [J] => Значение J2
            [K] => Значение K2
            [L] => Значение L2
            [M] => Значение M2
        )

    [3] => Array
        (
            [A] => Значение А3
            [B] => Значение В3
            [C] => Значение С3
            [D] => Значение D3
            [E] => Значение E3
            [F] => Значение F3
            [G] => Значение G3
            [H] => Значение H3
            [I] => Значение I3
            [J] => Значение J3
            [K] => Значение K3
            [L] => Значение L3
            [M] => Значение M3
        )

    [4] => Array
        (
            [A] => Значение А4
            [B] => Значение В4
            [C] => Значение С4
            [D] => Значение D4
            [E] => Значение E4
            [F] => Значение F4
            [G] => Значение G4
            [H] => Значение H4
            [I] => Значение I4
            [J] => Значение J4
            [K] => Значение K4
            [L] => Значение L4
            [M] => Значение M4
        )

    [5] => Array
        (
            [A] => Значение А5
            [B] => Значение В5
            [C] => Значение С5
            [D] => Значение D5
            [E] => Значение E5
            [F] => Значение F5
            [G] => Значение G5
            [H] => Значение H5
            [I] => Значение I5
            [J] => Значение J5
            [K] => Значение K5
            [L] => Значение L5
            [M] => Значение M5
        )

    [6] => Array
        (
            [A] => Значение А6
            [B] => Значение В6
            [C] => Значение С6
            [D] => Значение D6
            [E] => Значение E6
            [F] => Значение F6
            [G] => Значение G6
            [H] => Значение H6
            [I] => Значение I6
            [J] => Значение J6
            [K] => Значение K6
            [L] => Значение L6
            [M] => Значение M6
        )

    [7] => Array
        (
            [A] => Значение А7
            [B] => Значение В7
            [C] => Значение С7
            [D] => Значение D7
            [E] => Значение E7
            [F] => Значение F7
            [G] => Значение G7
            [H] => Значение H7
            [I] => Значение I7
            [J] => Значение J7
            [K] => Значение K7
            [L] => Значение L7
            [M] => Значение M7
        )

    [8] => Array
        (
            [A] => Значение А8
            [B] => Значение В8
            [C] => Значение С8
            [D] => Значение D8
            [E] => Значение E8
            [F] => Значение F8
            [G] => Значение G8
            [H] => Значение H8
            [I] => Значение I8
            [J] => Значение J8
            [K] => Значение K8
            [L] => Значение L8
            [M] => Значение M8
        )

    [9] => Array
        (
            [A] => Значение А9
            [B] => Значение В9
            [C] => Значение С9
            [D] => Значение D9
            [E] => Значение E9
            [F] => Значение F9
            [G] => Значение G9
            [H] => Значение H9
            [I] => Значение I9
            [J] => Значение J9
            [K] => Значение K9
            [L] => Значение L9
            [M] => Значение M9
        )

    [10] => Array
        (
            [A] => Значение А10
            [B] => Значение В10
            [C] => Значение С10
            [D] => Значение D10
            [E] => Значение E10
            [F] => Значение F10
            [G] => Значение G10
            [H] => Значение H10
            [I] => Значение I10
            [J] => Значение J10
            [K] => Значение K10
            [L] => Значение L10
            [M] => Значение M10
        )

    [11] => Array
        (
            [A] => Значение А11
            [B] => Значение В11
            [C] => Значение С11
            [D] => Значение D11
            [E] => Значение E11
            [F] => Значение F11
            [G] => Значение G11
            [H] => Значение H11
            [I] => Значение I11
            [J] => Значение J11
            [K] => Значение K11
            [L] => Значение L11
            [M] => Значение M11
        )

    [12] => Array
        (
            [A] => Значение А12
            [B] => Значение В12
            [C] => Значение С12
            [D] => Значение D12
            [E] => Значение E12
            [F] => Значение F12
            [G] => Значение G12
            [H] => Значение H12
            [I] => Значение I12
            [J] => Значение J12
            [K] => Значение K12
            [L] => Значение L12
            [M] => Значение M12
        )

    [13] => Array
        (
            [A] => Значение А13
            [B] => Значение В13
            [C] => Значение С13
            [D] => Значение D13
            [E] => Значение E13
            [F] => Значение F13
            [G] => Значение G13
            [H] => Значение H13
            [I] => Значение I13
            [J] => Значение J13
            [K] => Значение K13
            [L] => Значение L13
            [M] => Значение M13
        )

    [14] => Array
        (
            [A] => Значение А14
            [B] => Значение В14
            [C] => Значение С14
            [D] => Значение D14
            [E] => Значение E14
            [F] => Значение F14
            [G] => Значение G14
            [H] => Значение H14
            [I] => Значение I14
            [J] => Значение J14
            [K] => Значение K14
            [L] => Значение L14
            [M] => Значение M14
        )

    [15] => Array
        (
            [A] => Значение А15
            [B] => Значение В15
            [C] => Значение С15
            [D] => Значение D15
            [E] => Значение E15
            [F] => Значение F15
            [G] => Значение G15
            [H] => Значение H15
            [I] => Значение I15
            [J] => Значение J15
            [K] => Значение K15
            [L] => Значение L15
            [M] => Значение M15
        )

    [16] => Array
        (
            [A] => Значение А16
            [B] => Значение В16
            [C] => Значение С16
            [D] => Значение D16
            [E] => Значение E16
            [F] => Значение F16
            [G] => Значение G16
            [H] => Значение H16
            [I] => Значение I16
            [J] => Значение J16
            [K] => Значение K16
            [L] => Значение L16
            [M] => Значение M16
        )

    [17] => Array
        (
            [A] => Значение А17
            [B] => Значение В17
            [C] => Значение С17
            [D] => Значение D17
            [E] => Значение E17
            [F] => Значение F17
            [G] => Значение G17
            [H] => Значение H17
            [I] => Значение I17
            [J] => Значение J17
            [K] => Значение K17
            [L] => Значение L17
            [M] => Значение M17
        )

    [18] => Array
        (
            [A] => Значение А18
            [B] => Значение В18
            [C] => Значение С18
            [D] => Значение D18
            [E] => Значение E18
            [F] => Значение F18
            [G] => Значение G18
            [H] => Значение H18
            [I] => Значение I18
            [J] => Значение J18
            [K] => Значение K18
            [L] => Значение L18
            [M] => Значение M18
        )

    [19] => Array
        (
            [A] => Значение А19
            [B] => Значение В19
            [C] => Значение С19
            [D] => Значение D19
            [E] => Значение E19
            [F] => Значение F19
            [G] => Значение G19
            [H] => Значение H19
            [I] => Значение I19
            [J] => Значение J19
            [K] => Значение K19
            [L] => Значение L19
            [M] => Значение M19
        )

    [20] => Array
        (
            [A] => Значение А20
            [B] => Значение В20
            [C] => Значение С20
            [D] => Значение D20
            [E] => Значение E20
            [F] => Значение F20
            [G] => Значение G20
            [H] => Значение H20
            [I] => Значение I20
            [J] => Значение J20
            [K] => Значение K20
            [L] => Значение L20
            [M] => Значение M20
        )

    [21] => Array
        (
            [A] => Значение А21
            [B] => Значение В21
            [C] => Значение С21
            [D] => Значение D21
            [E] => Значение E21
            [F] => Значение F21
            [G] => Значение G21
            [H] => Значение H21
            [I] => Значение I21
            [J] => Значение J21
            [K] => Значение K21
            [L] => Значение L21
            [M] => Значение M21
        )

    [22] => Array
        (
            [A] => Значение А22
            [B] => Значение В22
            [C] => Значение С22
            [D] => Значение D22
            [E] => Значение E22
            [F] => Значение F22
            [G] => Значение G22
            [H] => Значение H22
            [I] => Значение I22
            [J] => Значение J22
            [K] => Значение K22
            [L] => Значение L22
            [M] => Значение M22
        )

    [23] => Array
        (
            [A] => Значение А23
            [B] => Значение В23
            [C] => Значение С23
            [D] => Значение D23
            [E] => Значение E23
            [F] => Значение F23
            [G] => Значение G23
            [H] => Значение H23
            [I] => Значение I23
            [J] => Значение J23
            [K] => Значение K23
            [L] => Значение L23
            [M] => Значение M23
        )

    [24] => Array
        (
            [A] => Значение А24
            [B] => Значение В24
            [C] => Значение С24
            [D] => Значение D24
            [E] => Значение E24
            [F] => Значение F24
            [G] => Значение G24
            [H] => Значение H24
            [I] => Значение I24
            [J] => Значение J24
            [K] => Значение K24
            [L] => Значение L24
            [M] => Значение M24
        )

    [25] => Array
        (
            [A] => Значение А25
            [B] => Значение В25
            [C] => Значение С25
            [D] => Значение D25
            [E] => Значение E25
            [F] => Значение F25
            [G] => Значение G25
            [H] => Значение H25
            [I] => Значение I25
            [J] => Значение J25
            [K] => Значение K25
            [L] => Значение L25
            [M] => Значение M25
        )

    [26] => Array
        (
            [A] => Значение А26
            [B] => Значение В26
            [C] => Значение С26
            [D] => Значение D26
            [E] => Значение E26
            [F] => Значение F26
            [G] => Значение G26
            [H] => Значение H26
            [I] => Значение I26
            [J] => Значение J26
            [K] => Значение K26
            [L] => Значение L26
            [M] => Значение M26
        )

    [27] => Array
        (
            [A] => Значение А27
            [B] => Значение В27
            [C] => Значение С27
            [D] => Значение D27
            [E] => Значение E27
            [F] => Значение F27
            [G] => Значение G27
            [H] => Значение H27
            [I] => Значение I27
            [J] => Значение J27
            [K] => Значение K27
            [L] => Значение L27
            [M] => Значение M27
        )

    [28] => Array
        (
            [A] => Значение А28
            [B] => Значение В28
            [C] => Значение С28
            [D] => Значение D28
            [E] => Значение E28
            [F] => Значение F28
            [G] => Значение G28
            [H] => Значение H28
            [I] => Значение I28
            [J] => Значение J28
            [K] => Значение K28
            [L] => Значение L28
            [M] => Значение M28
        )

    [29] => Array
        (
            [A] => Значение А29
            [B] => Значение В29
            [C] => Значение С29
            [D] => Значение D29
            [E] => Значение E29
            [F] => Значение F29
            [G] => Значение G29
            [H] => Значение H29
            [I] => Значение I29
            [J] => Значение J29
            [K] => Значение K29
            [L] => Значение L29
            [M] => Значение M29
        )

    [30] => Array
        (
            [A] => Значение А30
            [B] => Значение В30
            [C] => Значение С30
            [D] => Значение D30
            [E] => Значение E30
            [F] => Значение F30
            [G] => Значение G30
            [H] => Значение H30
            [I] => Значение I30
            [J] => Значение J30
            [K] => Значение K30
            [L] => Значение L30
            [M] => Значение M30
        )

)

В итоге все достаточно просто, каждая линия будет соответствовать номеру многомерного массива, где именами ключей будут выступать колонки их excel файла.

PHPExcel — библиотека для создания и чтения данных из файлов формата OpenXML (который используется в MS Excel 2007). С ее помощью можно считывать из файлов, записывать в файлы, форматировать содержимое, работать с формулами и т.д. Для работы PHPExcel требуется версия PHP 5.2 или выше, с установленными библиотеками Zip, XML и GD2.

Установка PHPExcel

Первым делом библиотеку необходимо скачать. Для этого переходим на официальный сайт библиотеки и скачиваем архив PHPExcel-1.7.8.zip. После распаковки мы получим несколько файлов и папок:

  • Classes
  • Documentation
  • Tests
  • changelog.txt
  • install.txt
  • license.txt

Файлы — это различные описания по предыдущим версиям, лицензионное соглашение и очень краткая инструкция по установке. Далее, в папке Classes, содержится непосредственно сама библиотека PHPExcel — эту папку необходимо скопировать в корень нашего скрипта.

В папке Documentation содержится документация по библиотеке на английском языке. В папке Tests — примеры по использованию библиотеки.

Создание Excel-файла

Итак, давайте создадим файл makeexcel.php и начинаем работать с ним. Для начала нам необходимо подключить главный файл библиотеки PHPExcel.php (который находится в папке Classes) и создать объект класса PHPExcel:

require_once 'Classes/PHPExcel.php';
$pExcel = new PHPExcel();

Настройки листа книги Excel

Документ Excel состоит из книг, а каждая книга в свою очередь, состоит из листов. Далее лист состоит из набора ячеек, доступ к которым осуществляется по координатам. То есть у нас есть столбцы, которые имеют буквенные имена (А, В, С и т.д) и есть строки, которые пронумерованы. Значит, что бы получить доступ к первой ячейке нужно указать код А1. Точно также мы с помощью библиотеки будем получать доступ к каждой ячейке.

Итак, первым делом необходимо выбрать активный лист, на который мы будем выводить данные и получить объект этого листа:

$pExcel->setActiveSheetIndex(0);
$aSheet = $pExcel->getActiveSheet();

С помощью метода setActiveSheetIndex(0) указываем индекс (номер) активного листа. Нумерация листов начинается с нуля. Далее с помощью метода getActiveSheet() получаем объект этого активного листа, то есть другими словами получаем доступ к нему для работы. И сохраняем этот объект в переменную $aSheet.

Если Вы захотите указать активным какой то другой лист, то вначале его необходимо создать, при помощи метода:

$pExcel->createSheet();

Затем, по аналогии, указываем индекс и получаем объект активного листа.

// Ориентация страницы и  размер листа
$aSheet->getPageSetup()
       ->setOrientation(PHPExcel_Worksheet_PageSetup::ORIENTATION_PORTRAIT);
$aSheet->getPageSetup()
       ->SetPaperSize(PHPExcel_Worksheet_PageSetup::PAPERSIZE_A4);
// Поля документа
$aSheet->getPageMargins()->setTop(1);
$aSheet->getPageMargins()->setRight(0.75);
$aSheet->getPageMargins()->setLeft(0.75);
$aSheet->getPageMargins()->setBottom(1);
// Название листа
$aSheet->setTitle('Прайс-лист');
// Шапка и футер (при печати)
$aSheet->getHeaderFooter()
       ->setOddHeader('&CТД ТИНКО: прайс-лист');
$aSheet->getHeaderFooter()
       ->setOddFooter('&L&B'.$aSheet->getTitle().'&RСтраница &P из &N');
// Настройки шрифта
$pExcel->getDefaultStyle()->getFont()->setName('Arial');
$pExcel->getDefaultStyle()->getFont()->setSize(8);

Вначале задаем ориентацию листа при помощи метода setOrientation(), которому передаем константу класса PHPExcel_Worksheet_PageSetup:

  • ORIENTATION_PORTRAIT — книжная
  • ORIENTATION_LANDSCAPE — альбомная

Обратите внимание, что перед методом setOrientation() необходимо вызвать метод getPageSetup(), который предоставляет доступ к настройкам страницы.

Далее вызываем метод SetPaperSize(), который позволяет задать размер страницы для печати. Ему передаем параметром константу PAPERSIZE_A4 класса PHPExcel_Worksheet_PageSetup. Что означает, что размер листа страницы будет установлен А4.

Далее устанавливаем поля документа, то есть отступы от краев документа. Отступы задаются в специальных символьных единицах. Вначале, обратите внимание, вызываем у объекта $aSheet метод getPageMargins(), который вернет объект класса, отвечающего за настройки полей страницы. Затем вызываем методы setTop(), setRight(), setLeft() и setBottom().

Далее при помощи метода setTitle(‘Прайс лист’) задаем название нашего листа.

Если нужно, можно при печати выводить шапку и подвал листа:

  • setOddHeader();
  • setOddFooter();

Обратите внимание на передаваемые параметры:

  • для шапки передаем строку ‘&CТД ТИНКО: прайс-лист’; метка &C означает, что текст нужно расположить по центру.
  • для подвала передаем строку ‘&L&B’.$aSheet->getTitle().’&RСтраница &P из &N’; это означает, что нужно вывести слева и жирным шрифтом (&L&B) название листа (метод $aSheet->getTitle()), затем справа (&R) вывести номер страницы (&P) из общего количества страниц (&N).

Затем указываем настройки шрифта по умолчанию:

  • setName(‘Arial’) — задаем имя шрифта;
  • setSize(8) — задаем размер шрифта.

Наполнение документа данными

Для начала давайте зададим ширину столбцов (в символьных единицах), которые нам понадобятся:

$aSheet->getColumnDimension('A')->setWidth(3);
$aSheet->getColumnDimension('B')->setWidth(7);
$aSheet->getColumnDimension('C')->setWidth(20);
$aSheet->getColumnDimension('D')->setWidth(40);
$aSheet->getColumnDimension('E')->setWidth(10);

Теперь заполним несколько ячеек текстом:

$aSheet->mergeCells('A1:E1');
$aSheet->getRowDimension('1')->setRowHeight(20);
$aSheet->setCellValue('A1','ТД ТИНКО');
$aSheet->mergeCells('A2:E2');
$aSheet->setCellValue('A2','Поставка технических средств безопасности');
$aSheet->mergeCells('A4:C4');
$aSheet->setCellValue('A4','Дата создания прайс-листа');

Здесь мы сначала объеденяем ячейки с А1 до E1 при помощи метода mergeCells(), далее задаем высоту строки: вначале получаем доступ к строке 1 при помощи метода getRowDimension(‘1’), затем задаем высоту — setRowHeight(20). Далее при помощи метода setCellValue(‘A1′,’ТД ТИНКО’), устанавливаем значение ячейки А1.

Создание Excel средствами PHP

Далее давайте в ячейку D4 запишем текущую дату:

// Записываем данные в ячейку
$date = date('d-m-Y');
$aSheet->setCellValue('D4',$date);
// Устанавливает формат данных в ячейке (дата вида дд-мм-гггг)
$aSheet->getStyle('D4')->getNumberFormat()
->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_DATE_XLSX14);

С помощью констант, определенных в классе PHPExcel_Style_NumberFormat, можно задать формат ячейки: FORMAT_GENERAL (общий), FORMAT_TEXT (текст), FORMAT_NUMBER (число), FORMAT_NUMBER_00 (число с дробной частью), FORMAT_PERCENTAGE (процент), FORMAT_PERCENTAGE_00 (процент с дробной частью) и т.п.

Теперь, используя метод setCellValue(), а также цикл while() наполним данными наш прайс-лист:

mysql_connect(DB_HOST, DB_USER, DB_PASS);
mysql_query('SET NAMES utf8');
mysql_select_db(DB_NAME);

// Создаем шапку таблички данных
$aSheet->setCellValue('A6','№');
$aSheet->setCellValue('B6','Код');
$aSheet->setCellValue('C6','Наименование');
$aSheet->setCellValue('D6','Описание');
$aSheet->setCellValue('E6','Цена');

$query = "SELECT `code`, `name`, `description`, `price` FROM `products` WHERE 1 LIMIT 10";
$res = mysql_query( $query );

$i = 1;
while( $prd = mysql_fetch_assoc($res) ) {
    $aSheet->setCellValue('A'.($i+6), $i);
    $aSheet->setCellValue('B'.($i+6), $prd['code']);
    $aSheet->setCellValue('C'.($i+6), $prd['name']);
    $aSheet->setCellValue('D'.($i+6), $prd['description']);
    $aSheet->setCellValue('E'.($i+6), $prd['price']);
    $i++;
}

Стилизация данных

Давайте немного украсим наш прайс-лист, то есть каждой ячейке добавим стилей. Для этого необходимо создать массив со стилями и при помощи метода applyFromArray(), применить этот массив к ячейке (или ячейкам):

// массив стилей
$style_wrap = array(
    // рамки
    'borders'=>array(
        // внешняя рамка
        'outline' => array(
            'style'=>PHPExcel_Style_Border::BORDER_THICK,
            'color' => array(
                'rgb'=>'006464'
            )
        ),
        // внутренняя
        'allborders'=>array(
            'style'=>PHPExcel_Style_Border::BORDER_THIN,
            'color' => array(
                'rgb'=>'CCCCCC'
            )
        )
    )
);

$aSheet->getStyle('A1:F'.($i+5))->applyFromArray($style_wrap);

Теперь, по аналогии, применим стили к остальным ячейкам:

// Стили для верхней надписи (первая строка)
$style_header = array(
    // Шрифт
    'font'=>array(
        'bold' => true,
        'name' => 'Times New Roman',
        'size' => 15,
        'color'=>array(
            'rgb' => '006464'
        )
    ),
    // Выравнивание
    'alignment' => array(
        'horizontal' => PHPExcel_STYLE_ALIGNMENT::HORIZONTAL_CENTER,
        'vertical' => PHPExcel_STYLE_ALIGNMENT::VERTICAL_CENTER,
    ),
    // Заполнение цветом
    'fill' => array(
        'type' => PHPExcel_STYLE_FILL::FILL_SOLID,
        'color'=>array(
            'rgb' => '99CCCC'
        )
    ),
    'borders'=>array(
        'bottom'=>array(
            'style'=>PHPExcel_Style_Border::BORDER_THIN,
            'color' => array(
                'rgb'=>'006464'
            )
        )
    )
);
$aSheet->getStyle('A1:E1')->applyFromArray($style_header);

// Стили для слогана компании (вторая строка)
$style_slogan = array(
    // шрифт
    'font'=>array(
        'bold' => true,
        'italic' => true,
        'name' => 'Times New Roman',
        'size' => 12,
        'color'=>array(
            'rgb' => '006464'
        )
    ),
    // выравнивание
    'alignment' => array(
        'horizontal' => PHPExcel_STYLE_ALIGNMENT::HORIZONTAL_CENTER,
        'vertical' => PHPExcel_STYLE_ALIGNMENT::VERTICAL_CENTER,
    ),
    // заполнение цветом
    'fill' => array(
        'type' => PHPExcel_STYLE_FILL::FILL_SOLID,
        'color'=>array(
            'rgb' => '99CCCC'
        )
    ),
    //рамки
    'borders' => array(
        'bottom' => array(
            'style'=>PHPExcel_Style_Border::BORDER_THIN,
            'color' => array(
                'rgb'=>'006464'
            )
        )
    )
);
$aSheet->getStyle('A2:E2')->applyFromArray($style_slogan);

// Стили для текта возле даты
$style_tdate = array(
    // выравнивание
    'alignment' => array(
        'horizontal' => PHPExcel_STYLE_ALIGNMENT::HORIZONTAL_RIGHT,
    ),
    // заполнение цветом
    'fill' => array(
        'type' => PHPExcel_STYLE_FILL::FILL_SOLID,
        'color'=>array(
            'rgb' => 'EEEEEE'
        )
    ),
    // рамки
    'borders' => array(
        'right' => array(
            'style'=>PHPExcel_Style_Border::BORDER_NONE
        )
    )
);
$aSheet->getStyle('A4:D4')->applyFromArray($style_tdate);
 
// Стили для даты
$style_date = array(
    // заполнение цветом
    'fill' => array(
        'type' => PHPExcel_STYLE_FILL::FILL_SOLID,
        'color'=>array(
            'rgb' => 'EEEEEE'
        )
    ),
    // рамки
    'borders' => array(
        'left' => array(
            'style'=>PHPExcel_Style_Border::BORDER_NONE
        )
    ),
);
$aSheet->getStyle('E4')->applyFromArray($style_date);
 
// Стили для шапки таблицы (шестая строка)
$style_hprice = array(
    // выравнивание
    'alignment' => array(
    'horizontal' => PHPExcel_STYLE_ALIGNMENT::HORIZONTAL_CENTER,
    ),
    // заполнение цветом
    'fill' => array(
        'type' => PHPExcel_STYLE_FILL::FILL_SOLID,
        'color'=>array(
            'rgb' => 'CFCFCF'
        )
    ),
    // шрифт
    'font'=>array(
        'bold' => true,
        /* 'italic' => true, */
        'name' => 'Times New Roman',
        'size' => 10
    ),
);
$aSheet->getStyle('A6:E6')->applyFromArray($style_hprice);

// Cтили для данных в таблице прайс-листа
$style_price = array(
    'alignment' => array(
    'horizontal' => PHPExcel_STYLE_ALIGNMENT::HORIZONTAL_LEFT,
    )
);
$aSheet->getStyle('A7:E'.($i+5))->applyFromArray($style_price);

Сохранение документа

Осталось только сохранить наш документ:

/*
$objWriter = PHPExcel_IOFactory::createWriter($pExcel, 'Excel5');
$objWriter->save('simple.xls');
*/
$objWriter = PHPExcel_IOFactory::createWriter($pExcel, 'Excel2007');
$objWriter->save('simple.xlsx');

или так

/*
$objWriter = new PHPExcel_Writer_Excel5($pExcel);
$objWriter->save('simple.xls');
*/
$objWriter = new PHPExcel_Writer_Excel2007($pExcel);
$objWriter->save('simple.xlsx');

Если нужно вывести документ в браузер

/*
header('Content-Type:application/vnd.ms-excel');
header('Content-Disposition:attachment;filename="simple.xls"');
$objWriter = new PHPExcel_Writer_Excel5($pExcel);
*/
header('Content-Type:xlsx:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header('Content-Disposition:attachment;filename="simple.xlsx"');
$objWriter = new PHPExcel_Writer_Excel2007($pExcel);
$objWriter->save('php://output');

Первый заголовок указывает браузеру тип открываемого контента — это документ формата Excel. Второй — говорит браузеру, что документ необходимо отдать пользователю на скачивание под именем simple.xlsx.

Добавление формул

Формула Excel — это математическое выражение, которое создается для вычисления результата и которое может зависеть от содержимого других ячеек. Формула в ячейке Excel может содержать данные, ссылки на другие ячейки, а также обозначение действий, которые необходимо выполнить.

Использование ссылок на ячейки позволяет пересчитывать результат по формулам, когда происходят изменения содержимого ячеек, включенных в формулы. Формулы Excel начинаются со знака =. Скобки ( ) могут использоваться для определения порядка математических операции.

Примеры формул Excel: =27+36, =А1+А2-АЗ, =SUM(А1:А5), =MAX(АЗ:А5), =(А1+А2)/АЗ.

PHPExcel тоже поддерживает добавление формул в ячейки. Установить формулу можно так:

// формула для вычисления суммы
$formula = '=SUM(D2:D4)';
$aSheet->setCellValue('D5', $formula);

Добавление формул

Чтение Excel-файла

Самый простой вариант — считать все таблицы (на всех листах) и записать данные в трехмерный массив:

// Подключаем библиотеку
require_once 'Classes/PHPExcel.php';
$pExcel = PHPExcel_IOFactory::load('simple.xlsx');

// Цикл по листам Excel-файла
foreach ($pExcel->getWorksheetIterator() as $worksheet) {
    // выгружаем данные из объекта в массив
    $tables[] = $worksheet->toArray();
}

Теперь можно вывести массив:

// Цикл по листам Excel-файла
foreach( $tables as $table ) {
    echo '<table border="1">';
    // Цикл по строкам
    foreach($table as $row) {
        echo '<tr>';
        // Цикл по колонкам
        foreach( $row as $col ) {
            echo '<td>'.$col.'</td>';
        }
        echo '</tr>';
    }
    echo '</table>';
}

Для получения значения отдельной ячейки:

// выбираем лист, с которым будем работать
$pExcel->setActiveSheetIndex(0);
$aSheet = $pExcel->getActiveSheet();
// получаем доступ к ячейке по номеру строки 
// (нумерация с единицы) и столбца (нумерация с нуля) 
$cell = $aSheet->getCellByColumnAndRow($col, $row);
// читаем значение ячейки
$value = $cell->getValue()

или так:

$value = $pExcel->getActiveSheet()->getCellValue('B2')

Еще два примера:

// Цикл по листам Excel-файла
foreach( $pExcel->getWorksheetIterator() as $worksheet ) {
    echo '<h2>Лист «'.$worksheet->getTitle().'»</h2>';
    echo '<table border="1">';
    // Цикл по строкам
    foreach( $worksheet->getRowIterator() as $row ) {
        echo '<tr>';
        // Цикл по колонкам
        foreach( $row->getCellIterator() as $cell ) {
            $value = $cell->getValue();
            // $calcValue = $cell->getCalculatedValue()
            // $dataType = PHPExcel_Cell_DataType::dataTypeForValue($value);
            echo '<td>'.$value.'</td>';
        }
        echo '</tr>';
    }
    echo '</table>';
}
// Цикл по листам Excel-файла
foreach ($pExcel->getWorksheetIterator() as $worksheet) {
    $worksheetTitle     = $worksheet->getTitle();
    $highestRow         = $worksheet->getHighestRow(); // например, 10
    $highestColumn      = $worksheet->getHighestColumn(); // например, 'E'
    $highestColumnIndex = PHPExcel_Cell::columnIndexFromString($highestColumn);
    $nrColumns = ord($highestColumn) - 64;
    echo '<h2>Лист «'.$worksheetTitle.'» ';
    echo $nrColumns . ' колонок (A-' . $highestColumn . ') ';
    echo ' и ' . $highestRow . ' строк.</h2>';
    echo '<table border="1">';
    // Цикл по строкам
    for ($row = 1; $row <= $highestRow; $row++) {
        echo '<tr>';
        // Цикл по колонкам
        for ($col = 0; $col < $highestColumnIndex; $col++) {
            $cell = $worksheet->getCellByColumnAndRow($col, $row);
            echo '<td>'.$cell->getValue().'</td>';
        }
        echo '</tr>';
    }
    echo '</table>';
}

Дополнительно

  • Документация разработчика PHPExcel на русском
  • Блог на Laravel 7, часть 17. Временная зона для пользователей, деплой на хостинг TimeWeb
  • Блог на Laravel 7, часть 16. Роль нового пользователя, сообщение админу о новом посте
  • Блог на Laravel 7, часть 15. Восстановление постов, slug для категории, поста и страницы
  • Блог на Laravel 7, часть 14. Валидация данных и права доступа при загрузке изображений
  • Блог на Laravel 7, часть 13. Загрузка и ресайз изображений для категорий и постов блога
  • Блог на Laravel 7, часть 12. Доп.страницы сайта в панели управления и в публичной части
  • Блог на Laravel 7, часть 11. Панель управления — назначение ролей и прав для пользователей

Поиск:
Excel • MS • PHP • Web-разработка

Каталог оборудования

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

Производители

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

Функциональные группы

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

Code Snippets Reading And Writing Excel Files

About

In this code snippet, we’ll learn how to read and write excel files in PHP.

We will use the PHPSpreadsheet library to read/write Excel files and we’ll learn how to read cells, find a specific string in a row or column, write to cells, set cell styling and formatting(like setting the border, background color, etc) and we’ll see how to insert images.

Let’s see how to do it in the example below.

Installing PHPSpreadsheet:

Install PHPSpreadsheet using Composer by opening your project directory in cmd and running this: 

composer require phpoffice/phpspreadsheet

If you don’t know what Composer is or how to use it check out this post I made.

Note:

You might have to enable the gd PHP extension for this to work. I first got this error:

Problem 1

    – Root composer.json requires phpoffice/phpspreadsheet ^1.18 -> satisfiable by phpoffice/phpspreadsheet[1.18.0].

    – phpoffice/phpspreadsheet 1.18.0 requires ext-gd * -> it is missing from your system. Install or enable PHP’s gd extension.

FIX: If you are using XAMPP like I am open up your php.ini file and add this: extension=gd to the bottom of it. Then save the file and restart the Apache webserver and try to install the package again. 

Reading Excel Files Code:

ReadExcel.php

<?php

//Include the dependencies using Composer.
require_once(dirname(__FILE__) ."\vendor\autoload.php");
require_once(dirname(__FILE__) ."\helperFunctions.php");


//Setup Excel reader///////////////////////////////////////////

//File to be read.
$inputFileName = dirname(__FILE__) . "\readme.xlsx"; 
$sheetname = "First Sheet";

//Make a new instance of the Xlsx rader.
$reader = new PhpOfficePhpSpreadsheetReaderXlsx();
//Load the excel file to be read.
$spreadsheet = $reader->load($inputFileName);     
//Get the sheet by name.
$sheet = $spreadsheet->getSheetByName($sheetname);   

///////////////////////////////////////////////////////////////


//Reading file/////////////////////////////////////////////////

//The row number of the header.
$columnNameRow = 1;
//The row number where our data starts.
$dataRow = $columnNameRow+1;

//If you don't know the exact column number you search for it with this helper function.
$column = findColumn($sheet, "greetings", $columnNameRow);
//Or if you need to search the rows:
//$row = findRow($sheet, "text to find", $column);

//Data array that will store the read data.
$readSheetData = [];

//Read rows until an empty one is hit.
$currentCellData = "/";
for($i = $dataRow; $currentCellData != ""; $i++){
    //Get cell data.
    $currentCellData = $sheet->getCellByColumnAndRow($column, $i)->getCalculatedValue();
    //If data is present add it to the data array. 
    if($currentCellData != null)
        $readSheetData[] = $currentCellData;
}

//Display data array.
foreach($readSheetData as $item)
    echo $item . "<br>";

////////////////////////////////////////////////////////////////
HelperFunctions.php

<?php

//Helper functions//////////////////////////////////////////////

function findColumn($spreadsheet, $word, $row){
    $column = 1;
    $cellContent = $spreadsheet->getCellByColumnAndRow($column, $row)->getValue();
    
    while($cellContent != $word){
        $column++;
        $cellContent = $spreadsheet->getCellByColumnAndRow($column, $row)->getValue(); 
    }

    return $column;
}

function findRow($spreadsheet, $word, $column){
    $row = 1;
    $cellContent = $spreadsheet->getCellByColumnAndRow($column, $row)->getValue();

    while($cellContent != $word) {
        $row++;
        $cellContent = $spreadsheet->getCellByColumnAndRow($column, $row)->getValue();                 
    } 

    return $row;
}

////////////////////////////////////////////////////////////////

Resulting Output:

PHP reading excel files whole code

PHP reading excel files result

Writing Excel Files Code:

WriteExcel.php

<?php

//Include the dependencies using Composer.
require_once(dirname(__FILE__) ."\vendor\autoload.php");

use PhpOfficePhpSpreadsheetSpreadsheet;
use PhpOfficePhpSpreadsheetWriterXlsx;
use PhpOfficePhpSpreadsheetWriterDrawing;


//Setup Excel writer////////////////////////////////////////////

//File to be read.
$inputFileName = dirname(__FILE__) . "readme.xlsx"; 
$sheetname = "First Sheet";

//Make a new spreadsheet.
$spreadsheet = new Spreadsheet();
//Get active sheet.
$sheet = $spreadsheet->getActiveSheet();
//Set sheet name.
$sheet->setTitle('Data');

////////////////////////////////////////////////////////////////


//Writing file//////////////////////////////////////////////////

$dataToWrite1 = [ 15465, 532185, 2566, 54886 ];
$dataToWrite2 = [ 5694, 56964, 321789, 45623 ];

//Make header(optional).
$sheet->setCellValue('A1', "Data Set 1");
$sheet->setCellValue('B1', "Data Set 2");
//Make a bottom border(optional).
$sheet->getStyle('A1:B1')->getBorders()->getBottom()->setBorderStyle(PhpOfficePhpSpreadsheetStyleBorder::BORDER_THIN);
//Set header background color(optional).
$sheet->getStyle('A1:B1')->getFill()->setFillType(PhpOfficePhpSpreadsheetStyleFill::FILL_SOLID)->getStartColor()->setRGB('d2d3d1');
//Set text bold.
$sheet->getStyle("A1:B1")->getFont()->setBold(true);
//Set auto resize(optional).
$sheet->getColumnDimension('A')->setAutoSize(true);

//For more styling/formatting info. check out the official documentation: https://phpspreadsheet.readthedocs.io/en/latest/

//Write data 1.
$i = 2;
foreach($dataToWrite1 as $item){
    //Write value into cell.
    $sheet->setCellValue('A'.$i, $item);
    //Set cell alignment(optional).
    $sheet->getStyle('A'.$i)->getAlignment()->setHorizontal(PhpOfficePhpSpreadsheetStyleAlignment::HORIZONTAL_CENTER);

    $i++;
}

//Write data 2.
$i = 2;
foreach($dataToWrite2 as $item){
    //Write value into cell.
    $sheet->setCellValue('B'.$i, $item);
    //Set cell alignment(optional).
    $sheet->getStyle('B'.$i)->getAlignment()->setHorizontal(PhpOfficePhpSpreadsheetStyleAlignment::HORIZONTAL_CENTER);

    $i++;
}

//Adding an image.

//Create drawing.
$objDrawing = new PhpOfficePhpSpreadsheetWorksheetMemoryDrawing();


//Get image path.
$imgPathName = dirname(__FILE__) . "\PHP Reading And Writing Excel Files.jpg";    

//Create gdImage from image.
$gdImage = imagecreatefromjpeg($imgPathName);
//Set gdImage as a property to drawing.
$objDrawing->setImageResource($gdImage);

//Set drawing properties.
$objDrawing->setName('Thumbnail');
$objDrawing->setDescription('PHP Reading And Writing Excel Files');
//Set file type.
$objDrawing->setRenderingFunction(PhpOfficePhpSpreadsheetWorksheetMemoryDrawing::RENDERING_JPEG);
$objDrawing->setMimeType(PhpOfficePhpSpreadsheetWorksheetMemoryDrawing::MIMETYPE_DEFAULT);

//Set position.
$objDrawing->setCoordinates('D1');
//Set position offset.
$objDrawing->setOffsetX(50);
$objDrawing->setOffsetY(50);                
//Set width and height.
$objDrawing->setWidth(400); 
$objDrawing->setHeight(100);

$objDrawing->setWorksheet($sheet);

//Write excel file.
$savePath = dirname(__FILE__);

$writer = new Xlsx($spreadsheet);
$writer->save($savePath . "\New File.xlsx");

////////////////////////////////////////////////////////////////

Resulting Output:

PHP writing excel files whole code

Related Posts:

Ezoicreport this ad

Leave a Reply

Понравилась статья? Поделить с друзьями:
  • Read excel files in javascript
  • Read excel files from python
  • Read excel files from java
  • Read excel file with python
  • Read excel file with java