PHPExcel从大型工作表中删除行

时间:2017-01-26 02:49:05

标签: php phpexcel

我正在尝试根据Cell B = 59/61等条件删除行。但是,PHPExcel非常缓慢地加载行。对于18000行/ 3MB的工作表,加载大约需要4小时30分钟。如何提高数据工作表的加载和删除速度?

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);

1 个答案:

答案 0 :(得分:0)

提高性能的一种方法是从电子表格的底部开始向上工作,而不是向下工作。

删除行时,PHPExcel必须检查其下方每行中的单元格,并在必要时调整这些单元格中的引用。这样做效率更高,当您从工作表底部向上工作时,需要更少的检查/更新。

如果您一次可以删除多行,那么效率也会高得多。如果你需要删除第15,16和17行;那么

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

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

因此花一点时间评估你的$DeletedRows数组寻找范围可能是有益的

如果不是在第一个循环中构建要删除的行号数组并在第二个循环中删除它们,而不是在第一个循环中删除它们,那么你的代码也会快得多... 1循环将不可避免地更快比2个循环

最后,您的方法存在一个主要缺陷。如果你的第一个循环告诉你需要删除第1,5行;你删除了第1行然后删除了5 ....除了第5行实际上是第4行,因为你删除了第1行,而你实际上刚刚删除了当你执行原始循环时第6行的行来评估要删除的行....从下到上工作可以防止这个问题,也可以提高效率