PhpSpreadsheetのメモリ最適化とPHPExcelからの移行手法

メモリ使用量の削減

PhpSpreadsheetはワークシートごとに各セルあたり約1KBのメモリを消費するため、大規模なブックでは迅速にメモリを消費します。セルキャッシュ機能により、PhpSpreadsheetはセルオブジェクトをメモリ内だけでなく、ディスクやAPCu、Redisなどの外部ストレージに保持できるようになります。これにより大規模ブックのメモリ使用量を削減できますが、データアクセス速度は低下します。

デフォルトではすべてのセルオブジェクトをメモリに保持しますが、PSR-16互換の実装を提供することで代替方法を指定できます。PhpSpreadsheetのキーは自動的に命名され、使用後に削除されるため、単一のキャッシュインスタンスを複数の用途で共有可能です。

セルキャッシュを有効にするには、以下のコードを実行します:

$storage = new CustomCacheAdapter();
\PhpOffice\PhpSpreadsheet\Settings::setCache($storage);

各ワークシートごとに個別のキャッシュが維持され、シートをインスタンス化する際に自動的に作成されます。ブックの読み込みを開始した後や最初のシートを作成した後では設定を変更できません。

TTLの注意点

一般的なキャッシュとは異なり、PhpSpreadsheetのデータは再生成できません。キャッシュに保存されたデータが後で取得できない場合、例外が発生します。したがって、キャッシュデータは第三者やTTLメカニズムによって削除されないよう、TTLを無効または十分な期間設定してください。

実装例

APCuを使用する場合

依存関係を追加:

composer require cache/simple-cache-bridge cache/apcu-adapter

設定コード:

$adapter = new \Cache\Adapter\Apcu\ApcuCachePool();
$cacheBridge = new \Cache\Bridge\SimpleCache\SimpleCacheBridge($adapter);
\PhpOffice\PhpSpreadsheet\Settings::setCache($cacheBridge);

Redisを使用する場合

依存関係を追加:

composer require cache/simple-cache-bridge cache/redis-adapter

設定コード:

$redisConn = new \Redis();
$redisConn->connect('127.0.0.1', 6379);
$adapter = new \Cache\Adapter\Redis\RedisCachePool($redisConn);
$cacheBridge = new \Cache\Bridge\SimpleCache\SimpleCacheBridge($adapter);
\PhpOffice\PhpSpreadsheet\Settings::setCache($cacheBridge);

PHPExcelからの移行

PhpSpreadsheetでは名前空間の導入やクラス名の変更が行われています。既存プロジェクトを移行するためのツールが用意されていますが、手動での修正も必要です。

自動移行ツール

ツールはPhpSpreadsheetに含まれています。カレントディレクトリから再帰的にスキャンし、ソースコードを変更します:

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

重要:このツールは元のソースコードを破壊的に変更します。事前にバックアップを取ってから実行してください。

手動で行う必要のある変更

リーダー/ライターの名前変更

旧名称 新名称
'CSV''Csv'
'Excel2007''Xlsx'
'Excel5''Xls'
'HTML''Html'
'PDF''Pdf'

IOFactoryの簡素化

以下のメソッドは廃止され、registerReader/registerWriterに置き換えられました:

// 旧
\OldExcel_IOFactory::addSearchLocation($type, $location, $classname);

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

廃止されたメソッド

// 旧
$worksheet->duplicateStyleArray($styles, $range, $advanced);

// 新
$worksheet->getStyle($range)->applyFromArray($styles, $advanced);

カラムインデックスの1ベース化

カラムインデックスが1から始まるよう変更されました:

// 旧
$cell = $worksheet->getCellByColumnAndRow($column, $row);

// 新
$cell = $worksheet->getCellByColumnAndRow($column + 1, $row);

タグ: PhpSpreadsheet psr-16 migration redis apcu

7月5日 21:09 投稿