ホームページ  >  記事  >  バックエンド開発  >  ボックス/スパウトを使用して大きな Excel テーブルを解析する方法

ボックス/スパウトを使用して大きな Excel テーブルを解析する方法

醉折花枝作酒筹
醉折花枝作酒筹転載
2021-07-22 17:34:052843ブラウズ

PHP が Excel を解析するための比較的有名なライブラリは、phpoffice/phpexcel です。実際に使用すると、Excel の数万行に遭遇すると、phpexcel のメモリ使用量が急増します。今日は、Excel を効率的に解析するもう 1 つの PHP ライブラリである box/spout を紹介します。

ボックス/スパウトを使用して大きな Excel テーブルを解析する方法

公式の紹介を参照してください: 高速かつスケーラブルな方法でスプレッドシート ファイルを読み書きする このライブラリが 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 サイトの他の関連記事を参照してください。

声明:
この記事はcsdn.netで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。