阅读大型Excel 2007时的内存(.xlsx)

时间:2016-02-09 17:29:10

标签: php memory-management out-of-memory phpexcel phpexcelreader

我正在使用PHPExcel,这是我多次使用过的。我现在遇到的问题是在阅读Excel2007文件(.xlsx - format)时。我正在做的只是循环.xlsx文件并按行/列创建数组,然后在读取操作后print_r() - 结果,以确保数据输出在导入之前是好的进入MySQL数据库。

现在,在阅读Excel2007 .xlsx文件(6MB)时输出失败,但有意思的是,如果我将文件保存为旧格式.xls(1992-2004 - Excel5),文件会变大(16MB)但输出正确。这让我觉得最初它不是一个内存问题,因为较旧的较大.xls文件(16MB)运行没有问题,几乎是.xlsx文件(6MB)的3倍。

出于测试目的,我在.xlsx(6MB)文件中复制了30行中的25行并创建了一个新的Excel2007 .xlsx并对较小的25行数据集运行导入并输出正确。这导致我认为这是一个记忆问题,但与.xlsx格式......

有关

我在Amazon Web Services上运行服务器,并且C4.Xlarge(16核,30GB RAM),所以我应该有足够的资源来运行此操作。

问题:为什么我的输出在读取较小的.xlsx文件与较大的.xls文件时失败,但随后以较小的.xlsx成功(25 -row)文件?

// PHP函数

function parse_xls($file){
    ini_set('memory_limit','-1');
    $type = PHPExcel_IOFactory::identify($file);
    $reader = PHPExcel_IOFactory::createReader($type);
    $reader->setReadDataOnly(true);
    $xls = $reader->load($file); 
    $sheet = $xls->getActiveSheet();
    $highestRow = $sheet->getHighestRow();
    $highestColumn = $sheet->getHighestColumn();
    $highestColumnIndex = PHPExcel_Cell::columnIndexFromString($highestColumn);
    for($row=2; $row <= ($highestRow+2); $row++){
        $import[$row] = [];
        for($col=0; $col < $highestColumnIndex; $col++){
            $result = $sheet->getCellByColumnAndRow($col, $row)->getValue();
            array_push($import[$row],$result);
        }
    }
    print_r($import);
    die();
}

1 个答案:

答案 0 :(得分:0)

对于大文件我使用chunkReadFilter

$iChunkSize=1000; for($iStartRow = $row_start; $iStartRow <= $totalRows; $iStartRow += $iChunkSize) { $objReader = $oExcel->SetCreateReader(); $oChunkFilter = new chunkReadFilter(); $objReader->setReadFilter($oChunkFilter); $oChunkFilter->setRows($iStartRow,$iChunkSize); $objReader->setReadFilter($oChunkFilter); $objReader->setReadDataOnly(true); $objPHPExcel = $objReader->load($files['path']); $objPHPExcel->setActiveSheetIndex($iList); $sFromCell = 'A'.$iStartRow; $aData = $objPHPExcel->getActiveSheet()->toArray(null,true,true,false,$sFromCell); // free memory unset($objPHPExcel); unset($objReader); unset($oChunkFilter); // parse data foreach ($aData as $sKey => $aValue) { ... } // real data rows if (count($aData) < $iChunkSize) { unset($aData); break; } unset($aData); }