PhpSpreadsheet is the next version of PHPExcel. It breaks compatibility to dramatically improve the code base quality through namespaces, PSR compliance, and use of latest PHP language features.
All efforts have shifted to PhpSpreadsheet. PHPExcel is no longer maintained. All contributions, patches, and new features should target PhpSpreadsheet.
RectorPHP can automatically migrate your codebase. Note that this support has been dropped from current releases of Rector, so you need to require an earlier release.
Installation
Assuming your files to be migrated live in src/, install the required packages:
composer require rector/rector:0.15.10 rector/rector-phpoffice phpoffice/phpspreadsheet --dev
Configuration
Initialize Rector configuration:
Add PHPOfficeSetList to your rector.php config:
declare(strict_types=1);
use Rector\Config\RectorConfig;
use Rector\PHPOffice\Set\PHPOfficeSetList;
return static function (RectorConfig $rectorConfig): void {
$rectorConfig->sets([
PHPOfficeSetList::PHPEXCEL_TO_PHPSPREADSHEET
]);
};
Run Migration
Execute Rector on your codebase:
vendor/bin/rector process src
For more details, see rector-phpoffice.
Manual Changes
RectorPHP should handle most changes, but you may need to apply some manual updates:
Renamed Readers and Writers
When using IOFactory::createReader(), IOFactory::createWriter(), and IOFactory::identify(), the reader/writer short names have changed:
| Before | After |
|---|
'CSV' | 'Csv' |
'Excel2003XML' | 'Xml' |
'Excel2007' | 'Xlsx' |
'Excel5' | 'Xls' |
'Gnumeric' | 'Gnumeric' |
'HTML' | 'Html' |
'OOCalc' | 'Ods' |
'OpenDocument' | 'Ods' |
'PDF' | 'Pdf' |
'SYLK' | 'Slk' |
Simplified IOFactory
The following methods have been replaced:
PHPExcel_IOFactory::getSearchLocations()
PHPExcel_IOFactory::setSearchLocations()
PHPExcel_IOFactory::addSearchLocation()
Use IOFactory::registerReader() and IOFactory::registerWriter() instead. IOFactory now relies on class autoloading.
// Before
\PHPExcel_IOFactory::addSearchLocation($type, $location, $classname);
// After
\PhpOffice\PhpSpreadsheet\IOFactory::registerReader($type, $classname);
Removed Deprecated Methods
Worksheet::duplicateStyleArray()
// Before
$worksheet->duplicateStyleArray($styles, $range, $advanced);
// After
$worksheet->getStyle($range)->applyFromArray($styles, $advanced);
DataType::dataTypeForValue()
// Before
DataType::dataTypeForValue($value);
// After
DefaultValueBinder::dataTypeForValue($value);
Conditional::getCondition()
// Before
$conditional->getCondition();
// After
$conditional->getConditions()[0];
Conditional::setCondition()
// Before
$conditional->setCondition($value);
// After
$conditional->setConditions($value);
Worksheet::getDefaultStyle()
// Before
$worksheet->getDefaultStyle();
// After
$worksheet->getParent()->getDefaultStyle();
Worksheet::setDefaultStyle()
// Before
$worksheet->setDefaultStyle($value);
// After
$worksheet->getParent()->getDefaultStyle()->applyFromArray([
'font' => [
'name' => $pValue->getFont()->getName(),
'size' => $pValue->getFont()->getSize(),
],
]);
Worksheet::setSharedStyle()
// Before
$worksheet->setSharedStyle($sharedStyle, $range);
// After
$worksheet->duplicateStyle($sharedStyle, $range);
Worksheet::getSelectedCell()
// Before
$worksheet->getSelectedCell();
// After
$worksheet->getSelectedCells();
Writer\Xls::setTempDir()
// Before
$writer->setTempDir();
// After - no replacement available
// Temporary storage directory can no longer be set
Autoloader
The class PHPExcel_Autoloader has been removed entirely and is replaced by Composer’s autoloading mechanism.
Writing PDF
PDF libraries must be installed via Composer. The following methods have been removed:
PHPExcel_Settings::getPdfRenderer()
PHPExcel_Settings::setPdfRenderer()
PHPExcel_Settings::getPdfRendererName()
PHPExcel_Settings::setPdfRendererName()
Use IOFactory::registerWriter() instead:
// Before
\PHPExcel_Settings::setPdfRendererName(PHPExcel_Settings::PDF_RENDERER_MPDF);
\PHPExcel_Settings::setPdfRenderer($somePath);
$writer = \PHPExcel_IOFactory::createWriter($spreadsheet, 'PDF');
// After
$writer = \PhpOffice\PhpSpreadsheet\IOFactory::createWriter($spreadsheet, 'Mpdf');
// Or alternatively
\PhpOffice\PhpSpreadsheet\IOFactory::registerWriter('Pdf', \PhpOffice\PhpSpreadsheet\Writer\Pdf\Mpdf::class);
$writer = \PhpOffice\PhpSpreadsheet\IOFactory::createWriter($spreadsheet, 'Pdf');
// Or alternatively
$writer = new \PhpOffice\PhpSpreadsheet\Writer\Pdf\Mpdf($spreadsheet);
Rendering Charts
Chart rendering for HTML or PDF outputs has been simplified. While JpGraph support is still available, the version distributed via Composer is no longer maintained.
The package mitoteam/jpgraph is distributed via Composer and is fully compatible with JpGraph. We recommend using it for chart rendering.
Install the dependency:
composer require mitoteam/jpgraph
Then configure it:
// Before
$rendererName = \PHPExcel_Settings::CHART_RENDERER_JPGRAPH;
$rendererLibrary = 'jpgraph3.5.0b1/src/';
$rendererLibraryPath = '/php/libraries/Charts/' . $rendererLibrary;
\PHPExcel_Settings::setChartRenderer($rendererName, $rendererLibraryPath);
// After
Settings::setChartRenderer(\PhpOffice\PhpSpreadsheet\Chart\Renderer\MtJpGraphRenderer::class);
PclZip and ZipArchive
Support for PclZip has been dropped in favor of the more complete PHP extension ZipArchive. The following have been removed:
PclZip
PHPExcel_Settings::setZipClass()
PHPExcel_Settings::getZipClass()
PHPExcel_Shared_ZipArchive
PHPExcel_Shared_ZipStreamWrapper
Cell Caching
Cell caching was heavily refactored to leverage PSR-16. Most classes related to this feature were removed:
PHPExcel_CachedObjectStorage_APC
PHPExcel_CachedObjectStorage_DiscISAM
PHPExcel_CachedObjectStorage_ICache
PHPExcel_CachedObjectStorage_Igbinary
PHPExcel_CachedObjectStorage_Memcache
PHPExcel_CachedObjectStorage_Memory
PHPExcel_CachedObjectStorage_MemoryGZip
PHPExcel_CachedObjectStorage_MemorySerialized
PHPExcel_CachedObjectStorage_PHPTemp
PHPExcel_CachedObjectStorage_SQLite
PHPExcel_CachedObjectStorage_SQLite3
PHPExcel_CachedObjectStorage_Wincache
Additionally:
\PhpOffice\PhpSpreadsheet::getCellCollection() was renamed to \PhpOffice\PhpSpreadsheet::getCoordinates()
\PhpOffice\PhpSpreadsheet::getCellCacheController() was renamed to \PhpOffice\PhpSpreadsheet::getCellCollection()
Refer to the memory saving documentation for migration guidance.
Dropped Conditionally Returned Cell
The following methods will always return the Worksheet, never the Cell or Rule:
Worksheet::setCellValue()
Worksheet::setCellValueByColumnAndRow() (deprecated)
Worksheet::setCellValueExplicit()
Worksheet::setCellValueExplicitByColumnAndRow() (deprecated)
Worksheet::addRule()
Migration example:
// Before
$cell = $worksheet->setCellValue('A1', 'value', true);
// After
$cell = $worksheet->getCell('A1')->setValue('value');
Standardized Keys for Styling
Array keys used for styling have been standardized to use the same wording and casing as getter and setter methods:
// Before
$style = [
'numberformat' => [
'code' => NumberFormat::FORMAT_CURRENCY_EUR_SIMPLE,
],
'font' => [
'strike' => true,
'superScript' => true,
'subScript' => true,
],
'alignment' => [
'rotation' => 90,
'readorder' => Alignment::READORDER_RTL,
'wrap' => true,
],
'borders' => [
'diagonaldirection' => Borders::DIAGONAL_BOTH,
'allborders' => [
'style' => Border::BORDER_THIN,
],
],
'fill' => [
'type' => Fill::FILL_GRADIENT_LINEAR,
'startcolor' => [
'argb' => 'FFA0A0A0',
],
'endcolor' => [
'argb' => 'FFFFFFFF',
],
],
];
// After
$style = [
'numberFormat' => [
'formatCode' => NumberFormat::FORMAT_CURRENCY_EUR_SIMPLE,
],
'font' => [
'strikethrough' => true,
'superscript' => true,
'subscript' => true,
],
'alignment' => [
'textRotation' => 90,
'readOrder' => Alignment::READORDER_RTL,
'wrapText' => true,
],
'borders' => [
'diagonalDirection' => Borders::DIAGONAL_BOTH,
'allBorders' => [
'borderStyle' => Border::BORDER_THIN,
],
],
'fill' => [
'fillType' => Fill::FILL_GRADIENT_LINEAR,
'startColor' => [
'argb' => 'FFA0A0A0',
],
'endColor' => [
'argb' => 'FFFFFFFF',
],
],
];
Dedicated Class for Coordinate Manipulation
Methods to manipulate coordinates that previously existed in PHPExcel_Cell have been extracted to \PhpOffice\PhpSpreadsheet\Cell\Coordinate:
absoluteCoordinate()
absoluteReference()
buildRange()
columnIndexFromString()
coordinateFromString()
extractAllCellReferencesInRange()
getRangeBoundaries()
mergeRangesInCollection()
rangeBoundaries()
rangeDimension()
splitRange()
stringFromColumnIndex()
Column Index Based on 1
Column indexes are now based on 1, not 0. Column A is index 1, consistent with rows starting at 1 and Excel’s COLUMN() function.
// Before
$cell = $worksheet->getCellByColumnAndRow($column, $row);
// Use StringHelper::stringIncrement($column) rather than ++$column if using PHP 8.5+
for ($column = 0; $column < $max; ++$column) {
$worksheet->setCellValueByColumnAndRow($column, $row, 'value');
}
// After
$cell = $worksheet->getCell([$column + 1, $row]);
// Use StringHelper::stringIncrement($column) rather than ++$column if using PHP 8.5+
for ($column = 1; $column <= $max; ++$column) {
$worksheet->setCellValue([$column, $row], 'value');
}
All the following methods are affected and now deprecated:
PHPExcel_Worksheet::cellExistsByColumnAndRow()
PHPExcel_Worksheet::freezePaneByColumnAndRow()
PHPExcel_Worksheet::getCellByColumnAndRow()
PHPExcel_Worksheet::getColumnDimensionByColumn()
PHPExcel_Worksheet::getCommentByColumnAndRow()
PHPExcel_Worksheet::getStyleByColumnAndRow()
PHPExcel_Worksheet::insertNewColumnBeforeByIndex()
PHPExcel_Worksheet::mergeCellsByColumnAndRow()
PHPExcel_Worksheet::protectCellsByColumnAndRow()
PHPExcel_Worksheet::removeColumnByIndex()
PHPExcel_Worksheet::setAutoFilterByColumnAndRow()
PHPExcel_Worksheet::setBreakByColumnAndRow()
PHPExcel_Worksheet::setCellValueByColumnAndRow()
PHPExcel_Worksheet::setCellValueExplicitByColumnAndRow()
PHPExcel_Worksheet::setSelectedCellByColumnAndRow()
PHPExcel_Worksheet::stringFromColumnIndex()
PHPExcel_Worksheet::unmergeCellsByColumnAndRow()
PHPExcel_Worksheet::unprotectCellsByColumnAndRow()
PHPExcel_Worksheet_PageSetup::addPrintAreaByColumnAndRow()
PHPExcel_Worksheet_PageSetup::setPrintAreaByColumnAndRow()
Removed Default Values
Default values for many methods were removed when they didn’t make sense. Setter methods should not have default values. For a complete list of methods and their original default values, see this commit.