web-dev-qa-db-ja.com

PHPSpreadsheetを使用した非常に大きなスプレッドシートの作成

PHPSpreadsheetが大規模なExcelスプレッドシートでどのように機能するかをテストしています。最初のテストでは、大きなスプレッドシートの場合、すぐにメモリ不足になることが示されています。

スプレッドシートを段階的に作成する方法はありますか?

PHPからスプレッドシートを作成するために長い間使用してきた古いコードがあります。それは非常に古い規格を使用しており、更新が予定されています。しかし、私の古いコードの利点の1つは、全体をメモリに構築するのではなく、ファイルに書き込むことができるため、メモリの制限を超えずに非常に大きなスプレッドシートに簡単に対処できることです。

PHPSpreadsheetでも同様のことができますか?私はドキュメントを読み、さまざまなフォーラムを検索してみましたが、ほとんどの応答は「利用可能なメモリを増やす」だけのようです。

12
xtempore

残念ながら、PHPExcelとPHPSpreadsheetは大きなファイルに対してはあまりパフォーマンスが良くありません。

あなたのオプションはかなり制限されています:

  • メモリ制限を増やし続けます
  • データを個別のスプレッドシートに分割する
  • CSVへのフォールバック(PHPの組み込み関数を使用)

Maartenからのキャッシュの提案はいいアイデアですが、私の経験では、メモリの利点を完全に打ち消す巨大なスピードコストが伴いました。


私の提案は、PHPSpreadsheetを完全に捨てて box/spoutを試すことです

パフォーマンスを念頭に置いて構築されており、ファイルサイズに関係なく3MB未満のメモリを使用することを約束します。メモリ効率が良いだけでなく、PHPSpreadsheetよりも約20〜30倍高速でした。

これにはいくつかの制限があります(3つのファイル形式のみがサポートされ、自動列幅、列番号/文字列の書式設定はありません)。これらの欠落している機能のいくつかは計画されていると思います。 。

注:私はプロジェクトとは関係ありません

6
andrewtweber

彼らのドキュメントにはこれに関するトピックがあります:

https://phpspreadsheet.readthedocs.io/en/develop/topics/memory_saving/

基本的に、例えばRedis(のドキュメントから)のように、セルをキャッシュに保存できます。

$client = new \Redis();
$client->connect('127.0.0.1', 6379);
$pool = new \Cache\Adapter\Redis\RedisCachePool($client);
$simpleCache = new \Cache\Bridge\SimpleCache\SimpleCacheBridge($pool);

\PhpOffice\PhpSpreadsheet\Settings::setCache($simpleCache);

Predisを使用する場合は、次のリポジトリを使用できます。

https://github.com/php-cache/predis-adapter

そして、このコードを使用してください:

$client = new \Predis\Client($yourParameters, $yourOptions);
$pool = new \Cache\Adapter\Predis\PredisCachePool($client);
$simpleCache = new \Cache\Bridge\SimpleCache\SimpleCacheBridge($pool);

\PhpOffice\PhpSpreadsheet\Settings::setCache($simpleCache);
0
Maarten Manders