PhpSpreadsheet/docs/topics/migration-from-PHPExcel.md

8.0 KiB

Migration from PHPExcel

PhpSpreadsheet introduced many breaking changes by introducing namespaces and renaming some classes. To help you migrate existing project, a tool was written to replace all references to PHPExcel classes to their new names. But they are also manual changes that need to be done.

Automated tool

The tool is included in PhpSpreadsheet. It scans recursively all files and directories, starting from the current directory. Assuming it was installed with composer, it can be run like so:

cd /project/to/migrate/src
/project/to/migrate/vendor/phpoffice/phpspreadsheet/bin/migrate-from-phpexcel

Important The tool will irreversibly modify your sources, be sure to backup everything, and double check the result before committing.

Manual changes

In addition to automated changes, a few things need to be migrated manually.

Renamed readers and writers

When using with IOFactory::createReader(), IOFactory::createWriter() and IOFactory::identify(), the reader/writer short names are used. Those were changed, along as their corresponding class, to remove ambiguity:

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 :

  • PHPExcel_IOFactory::getSearchLocations()
  • PHPExcel_IOFactory::setSearchLocations()
  • PHPExcel_IOFactory::addSearchLocation()

were replaced by IOFactory::registerReader() and IOFactory::registerWriter(). That means IOFactory now relies on classes autoloading.

Before:

\PHPExcel_IOFactory::addSearchLocation($type, $location, $classname);

After:

\PhpOffice\PhpSpreadsheet\IOFactory::registerReader($type, $classname);

Removed deprecated things

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, there is no way to set temporary storage directory anymore

Autoloader

The class PHPExcel_Autoloader was removed entirely and is replaced by composer autoloading mechanism.

Writing PDF

PDF libraries must be installed via composer. And the following methods were removed and are replaced by IOFactory::registerWriter() instead:

  • PHPExcel_Settings::getPdfRenderer()
  • PHPExcel_Settings::setPdfRenderer()
  • PHPExcel_Settings::getPdfRendererName()
  • PHPExcel_Settings::setPdfRendererName() were renamed as setDefaultPdfWriter()

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);

PclZip and ZipArchive

Support for PclZip were dropped in favor of the more complete and modern PHP extension ZipArchive. So the following were 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. That means most classes related to that 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

In addition to that, \PhpOffice\PhpSpreadsheet::getCellCollection() was renamed to \PhpOffice\PhpSpreadsheet::getCoordinates() and \PhpOffice\PhpSpreadsheet::getCellCacheController() to \PhpOffice\PhpSpreadsheet::getCellCollection() for clarity.

Refer to the new documentation to see how to migrate.

Dropped conditionally returned cell

For all the following methods, it is no more possible to change the type of returned value. It always return the Worksheet and never the Cell or Rule:

  • Worksheet::setCellValue()
  • Worksheet::setCellValueByColumnAndRow()
  • Worksheet::setCellValueExplicit()
  • Worksheet::setCellValueExplicitByColumnAndRow()
  • Worksheet::addRule()

Migration would be similar to:

// 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 for a more coherent experience. It now uses the same wording and casing as the getter and setter:

// 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',
        ],
    ],
];