2017-08-31 11 views
0

約24 MBの大きさのxlsxファイルがあります。最初の行だけを読んでも時間がかかりすぎます。スパウトが各行を一つずつ読んでいたら、最初の行だけを読まなければならないのに時間がかかりすぎるのはなぜですか?spout phpで大きなxlsxを読むことができません

次は、この問題について理由が何であるか私を助けることができる完全なコード

require_once 'src/Spout/Autoloader/autoload.php'; 
$file_path = $_SERVER["DOCUMENT_ROOT"].'spout'.'/'.'testdata.xlsx'; 
use Box\Spout\Reader\ReaderFactory; 
use Box\Spout\Common\Type; 
libxml_disable_entity_loader(false); 

try { 
    //Lokasi file excel  
    $reader = ReaderFactory::create(Type::XLSX); //set Type file xlsx 
    $reader->open($file_path); //open the file   

    $i = 0; 

    /**     
    * Sheets Iterator. Kali aja multiple sheets     
    **/   
    foreach ($reader->getSheetIterator() as $sheet) { 
     //Rows iterator     
     foreach ($sheet->getRowIterator() as $row) { 
      echo $i."<hr>"; 
      if($i==0) // if first row 
      { 
       print_r($row); 
       exit; // exist after reading first row 
      } 
      ++$i; 
     }  
     exit; 
    } 
    echo "Total Rows : " . $i;    
    $reader->close(); 
    echo "Peak memory:", (memory_get_peak_usage(true)/1024/1024), " MB"; 
} 
catch (Exception $e) { 
    echo $e->getMessage(); 
    exit; 
} 

です。どうすればいいですか? あなたがhttp://www.mediafire.com/file/y369njsaeeah1ip/testdata.xlsx

Excelファイルでテストのxlsxファイルを見つけることができますが、以下の内容が含まれています:行の

  • 数:列の999991
  • 数:4(すなわちMPN、CATEGORY、MFG、説明)
  • ファイルサイズは約24 MBで、フォーマットは含まれていません。 enter image description here
+3

質問の本文にファイルの一部を投稿したり、行数や列数などの情報を投稿することをお勧めします。適切な考え方の誰もランダムなExcelファイルを開かないインターネットから。 – theFunkyEngineer

+0

ありがとうございます。私は私の質問を更新してくださいそれを確認してください。 – user3264863

答えて

0

XLSXファイルでセルデータを格納するための2通りの方法があります。

  1. 最も簡単な1が細胞構造のセル値を維持することである(すなわち、セル「A1」は「foo」を含んでいます、 "B1"は "bar"を含む)。
  2. もう1つの方法は、スプレッドシートで使用されているさまざまな値を追跡し、重複を削除するのに役立つリダイレクトのレイヤーを追加することです。これは2つのファイルに変換されます。 ID1 => ID2、 "C1" => ID1)と値(ID1 => "foo"、ID2 => "bar")を記述する値が含まれています。

方法2は、N回使用される値が1回だけ(しかし、N回参照される)格納されるため、ファイルのサイズを最適化します。ただし、これらの値を読み取るには、構造を読み込むときに2つのファイルを読み込み、マッピングを準備する必要があります。基本的に、最初の行を読み取るには、構造体を読み込んでセル(A1、B1、C1)を取得し、IDを使用して値を解決する必要があります。

インラインメソッドは、すべてが同じ場所に格納されるため、構造と値を同時に読み取ることができるため、より簡単です。マッピングテーブルは必要ありません。

今すぐ問題に戻る!読み込もうとしているファイルは、方法2(スプレッドシートの構造を記述するファイル+すべての値を含むファイル)を使用している可能性が最も高いです。読者がSpoutを読み込むと、値を含むファイルが処理され、準備ができた行を開始するたびにマッピングが準備されます。

多くの値がある場合は、この処理に時間がかかることがあります。特定のしきい値(利用可能なメモリの量に依存します)よりも低い場合、Spoutは[ID =>値]のマッピングをメモリにロードします。これはかなり高速です。しかし、値が多すぎると、Spoutはすべてがメモリに収まらないと判断し、ディスク上のマッピングのチャンクをキャッシュします。このプロセスは間違いなく時間がかかります...

これはあなたの場合に起こっていることです。うまくいけば、それは今より意味をなさない。 最終的にSpoutは現在のところメモリ不足を避けるために非常に防御的なので、しきい値は高くなります。

関連する問題