PHP が Excel を解析するための比較的有名なライブラリは、phpoffice/phpexcel です。実際に使用すると、Excel の数万行に遭遇すると、phpexcel のメモリ使用量が急増します。今日は、Excel を効率的に解析するもう 1 つの PHP ライブラリである box/spout を紹介します。
公式の紹介を参照してください: 高速かつスケーラブルな方法でスプレッドシート ファイルを読み書きする このライブラリが Excel を解析すると、Excel ファイルのサイズがメモリにはあまり影響しません。 PHPExcelの代替とも言えます。
Github ホームページ上のボックス/スパウト ライブラリのドキュメント リンクがダウンしているため、XLSX ファイルを CSV に変換する簡単な例を次に示します。
include 'vendor/autoload.php'; use Box\Spout\Reader\ReaderFactory; use Box\Spout\Common\Type; $t = time(); $reader = ReaderFactory::create(Type::XLSX); //如果注释掉,单元格内的日期类型将会是DateTime,不注释的话Spout自动帮你将日期转化成string //$reader->setShouldFormatDates(true); $reader->open('./test.xlsx'); $iterator = $reader->getSheetIterator(); $iterator->rewind(); $sheet1 = $iterator->current(); $rowIter = $sheet1->getRowIterator(); foreach ($rowIter as $row) { $d = ''; foreach ($row as $col) { echo $d; if ($col instanceof DateTime) { echo $col->format('Y-m-d'); } else { echo $col; } $d = "\t"; } echo PHP_EOL; } $reader->close();
使用方法はまだ非常に複雑です。シンプルかつ明確。
前述したように、解析中にボックス/スパウトによって消費されるメモリ サイズは Excel ファイルのサイズには影響されません。
ここで簡単な科学を説明します。XLSX ファイル形式は、OOXML (https://zh.wikipedia.org/zh-cn/Office_Open_XML) と呼ばれる標準に準拠しています。 XLSX は実際には、解凍して内容を確認できる Zip パッケージです。
XLSX テーブルでは、セルの内容が文字列の場合、実際の保存時には stringId のみが保存され、文字列の実際の内容は String ディクショナリに保存されます。
XLSX ファイルを読み取るときに、セルが文字列の場合、Spout は文字列辞書をクエリします。 Spout には 2 つのクエリ方法があり、1 つは毎回ファイルから辞書の一部を読み取る方法、もう 1 つは辞書全体をメモリに読み込んでクエリを実行する方法です。
明らかに、文字列ディクショナリ全体をメモリにロードする方がクエリ速度が最も速くなります。ただし、Spout は保守的すぎるため、多くの場合、最初のクエリ方法が使用されます。そこで、Spout コードを少し変更して、Spout がすべての辞書をメモリにロードできるようにします:
# Spout/Reader/XLSX/Helper/SharedStringsCaching/CachingStrategyFactory.php class CachingStrategyFactory { .... const MAX_NUM_STRINGS_PER_TEMP_FILE = 10000; // 改成50000 .... }
1.3w 行、28 列、2.8MB サイズの EXCEL を比較のために CSV に変換してみます:
方法 | 時間がかかります | メモリを占有します |
---|---|---|
辞書はメモリにロードされていません | 185 s | 1.3 MB |
辞書がメモリにロードされました | 43 s | 9.4 MB |
処理時間の差がかなり大きいことがわかります。
推奨学習: php ビデオ チュートリアル
以上がボックス/スパウトを使用して大きな Excel テーブルを解析する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。