2017-01-26 10 views
1

セルB = 59/61などの条件に基づいて行を削除しようとしています。しかし、PHPExcelは非常にゆっくりとローをロードします。 18000行/ 3MBのワークシートの場合、ロードに約4時間30分かかります。ロードして削除するデータワークシートの速度を改善するにはどうすればよいですか?大きなワークシートから行を削除するPHPExcel

set_include_path(get_include_path() . PATH_SEPARATOR . 'Classes/'); 
/** PHPExcel_IOFactory */ 
include 'PHPExcel/IOFactory.php'; 
//Defining File Type 
$fileType = "Excel2007"; 
//Retrieving File 
$tmpfname = "bigfile.xlsx"; 
//Loading file into PHPExcel 
$objPHPExcel = PHPExcel_IOFactory::load($tmpfname); 
$worksheet = $objPHPExcel->getSheet(0); //Worksheet of file defined as first 
$lastRow = $worksheet->getHighestRow(); 
//Determine which rows to be remove 
$DeletedRows = []; 
$DeletedRowCount = 0; 
for ($row = 2; $row <= $lastRow; $row++) { 
    //Checker 
    $CellA = $worksheet->getCell('A' . $row)->getValue(); 
    $CellB = $worksheet->getCell('B' . $row)->getValue(); 
    $CellE = $worksheet->getCell('E' . $row)->getValue(); 
    //To check condition 
    if ($CellB != 8 && $CellB != 9 && $CellB != 18 && $CellB != 19) { 
     $DeletedRows[] = $row; 
     continue; 
    } 
    //To check if condition 
    else if ($CellE == 59 || $CellE == 61){ 
     $DeletedRows[] = $row; 
     continue; 
    } 
} 
//Removing the rows 
//Deleting this way as when one row deleted, one row less. 
foreach ($DeletedRows as $key => $value) { 
    $row = $value - $DeletedRowCount; 
    $objPHPExcel->getActiveSheet()->removeRow($row, 1); 
    $DeletedRowCount++; 
} 
//Write file into original file 
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, $fileType); 
$objWriter->save($tmpfname); 

答えて

0

パフォーマンスを向上させる方法の1つは、下向きではなくスプレッドシートの下から上向きに作業することです。

行を削除するとき、PHPExcelは行を削除する際に、その下のすべての行のセルをチェックし、必要に応じてそれらのセルの参照を調整する必要があります。これは、ワークシートの下部から上に向かって作業するときに必要なチェック/更新が少なくて済むので、効率的です。


一度に複数の行を削除することもできます。行15,16、および17を削除する必要がある場合。その後、

$objPHPExcel->getActiveSheet()->removeRow(15, 3); 

は範囲を探して、あなたの$DeletedRows配列がはるかに高速


あなたのコードもなり有益であり得る

$objPHPExcel->getActiveSheet()->removeRow(15, 1); 
$objPHPExcel->getActiveSheet()->removeRow(16, 1); 
$objPHPExcel->getActiveSheet()->removeRow(17, 1); 

ので、評価時間のビットを費やすよりも3倍高速であります最初のループで削除する行番号の配列を作成し、2番目の行で削除する代わりに、最初のループで削除する場合は... 1のループは必然的に速くなります2ループ以上


最後に、あなたのアプローチには大きな欠陥が1つあります。最初のループから行1,5を削除する必要があることがわかった場合は、行1と5を削除します。ただし、行1を削除してから行5が実際に行4になり、削除する行を評価するために元のループを実行したときに行6だった行が削除されました。 ....下から上への作業は、この問題を防ぐだけでなく、より効率的です。

関連する問題