Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Rector Phpoffice Laravel Package

rector/rector-phpoffice

Rector rules for PhpOffice libraries that automate upgrading PhpSpreadsheet, PhpWord, and related packages. It applies safe, version-aware code transformations so you can modernize legacy PhpOffice code with less manual work and fewer regressions.

View on GitHub
Deep Wiki
Context7

Getting Started

This package provides Rector rules that automate the mechanical parts of migrating legacy PHPExcel (PHPExcel_*) code to PhpSpreadsheet (PhpSpreadsheet\*). It is not a runtime library — think of it as a one-shot codemod you run in a branch, review, and discard.

Minimal setup in a Laravel app that still references PHPExcel_* classes (common in older codebases, custom import/export services, or vendored scripts):

composer require --dev rector/rector rector/rector-phpoffice

Create rector.php at the project root:

<?php

use Rector\Config\RectorConfig;
use RectorPhpOffice\Set\PhpOfficeSetList; // verify exact FQCN in the package README

return RectorConfig::configure()
    ->withPaths([
        __DIR__ . '/app',
        __DIR__ . '/database',
    ])
    ->withSets([
        PhpOfficeSetList::PHP_OFFICE_TO_PHPSPREADSHEET,
    ]);

Then, before touching anything else, run a dry run to see the blast radius:

vendor/bin/rector process --dry-run

Where to look first: read the package's README and config/sets/ directory to confirm the exact set name and which rules are bundled. Stars and dependent counts are effectively zero here, so treat the package source as the source of truth over any blog post. Also grep your codebase for PHPExcel first — if nothing matches, you don't need this package at all (Maatwebsite/Laravel-Excel, for example, already targets PhpSpreadsheet and wouldn't benefit).

First real use case: a legacy import service that still calls PHPExcel_IOFactory::load(), PHPExcel_Cell::columnIndexFromString(), and getActiveSheet(). Run Rector on only that directory with --dry-run, eyeball the diff, then apply.

Implementation Patterns

Branch-per-migration workflow. Because Rector rewrites code in place, do the migration on a dedicated branch and commit the raw Rector output before any manual fixes. That gives you a clean diff to review and makes it trivial to cherry-pick or revert individual files.

Three-phase migration:

  1. Composer swap first. Change phpoffice/phpexcel → phpoffice/phpspreadsheet in composer.json, update the lockfile, and let the autoloader fail loudly. Rector only rewrites source; it can't fix your dependency graph.
  2. Run Rector to rename classes, namespaces, and the mechanical method calls it knows about.
  3. Hand-fix the residue — the parts of the API that changed shape rather than name (writer/reader options, style objects, PHPExcel_Settings constants).

Scope it narrow. Point withPaths() at the modules that actually import PHPExcel rather than __DIR__ . '/app'. Rector walks everything you give it, and a broad path set slows runs and produces noise in files that have nothing to do with the migration.

Layer with your existing Rector setup. If you already run Rector for upgrades (e.g. LevelSetList::UP_TO_PHP_82), put the PHPOffice set in the same config so one rector process applies both — but on the migration branch, run the PHPOffice set alone first so you can attribute every change.

Pair with static analysis as a safety net. After running Rector, run PHPStan or Psalm against the changed files. Rector's renames produce code that looks correct but can reference methods that no longer exist with the same signature. Static analysis catches those before tests do.

CI guard (optional). Add a small CI step that runs rector process --dry-run on the legacy paths and fails if it would change anything — this keeps new PHPExcel usage from creeping back in during the migration window.

Gotchas and Tips

  • Adoption risk is the headline gotcha. Zero stars, zero dependents, and a score of 26/100 means this is effectively a hobby/experimental ruleset. Pin an exact version, read the rule sources before trusting them, and be prepared to write your own rules if the package falls short. Budget time for that rather than assuming full coverage.
  • PHPExcel → PhpSpreadsheet is not a pure rename. The mechanical renames (PHPExcel_IOFactory → PhpSpreadsheet\IOFactory, PHPExcel_Worksheet → PhpSpreadsheet\Worksheet\Worksheet, etc.) are the easy 60%. Writers, readers, IOFactory::createWriter(), chart handling, and Calculation\Calculation all changed signatures. Rector output will still need manual review.
  • Not all PHPExcel_* classes map cleanly. Some were split, renamed into sub-namespaces, or removed. Expect unresolved class references after the run — grep the diff for leftover PHPExcel strings rather than trusting the tool ran to completion.
  • Underscore naming is fragile. PHPExcel's PHPExcel_Foo_Bar convention maps to nested namespaces in PhpSpreadsheet, and edge cases (e.g. PHPExcel_Shared_Date, PHPExcel_Style_*) may or may not be covered depending on the package's rule list. Cross-check each renamed class against the PhpSpreadsheet source.
  • Clear the Rector cache between runs. vendor/bin/rector clear-cache if a change seems to be ignored — the cache can mask edits after you tweak rector.php.
  • Use --dry-run and --diff together. --dry-run shows what would change; without it you're editing files blind. On a legacy codebase the first run can be alarming — start on a single file (vendor/bin/rector process app/Services/LegacyExport.php --dry-run) to calibrate.
  • Laravel-specific caveat: if the app uses maatwebsite/excel, that wrapper already targets PhpSpreadsheet and typically exposes an Excel:: facade — don't let a broad Rector path set touch those files. Exclude app/Exports, app/Imports unless you're certain they contain raw PHPExcel.
  • Extension points: add custom rules in a local utils/rector/ directory and register them in rector.php for any PHPExcel pattern the package misses (e.g. a project-specific wrapper class). Rector's own docs cover writing AbstractRector subclasses; that's your escape hatch if the package stagnates.
  • Config quirk to verify: confirm the exact set constant name (e.g. PHP_OFFICE_TO_PHPSPREADSHEET vs a set file path like __DIR__ . '/vendor/rector/rector-phpoffice/config/set/php-office.php'). With so little documentation, misreading the constant is the most common first-run failure.
  • Delete the package when done. This is a migration tool, not a runtime dependency. Once the diff is reviewed and merged, remove it from require-dev so a future composer update doesn't reintroduce an unmaintained ruleset into your dependency tree.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource