【问题标题】:PHPExcel memory issuePHPExcel内存问题
【发布时间】:2011-08-11 10:06:28
【问题描述】:

我正在尝试遍历一个 3mb 的 Excel 文档,以获取我必须插入到数据库中的所有数据。我正在使用的工作表有 6500 行,但将来可能会有所不同。我注意到即使我使用推荐的内存节省技术,它仍然会出错

$reader = PHPExcel_IOFactory::createReaderForFile($file_path);
$reader->setReadDataOnly(true);

//$sheets = $this->getWorksheetNames($file['tmp_name'], 0);
$reader->setLoadSheetsOnly('spreadsheetname');

$chunkFilter = new IPO_Reader(); 
$reader->setReadFilter($chunkFilter); 

$highestRow    = 10000; //$this->objWorksheet->getHighestRow();
$chunkSize     = 1; 
$highestColumn = "Y";

for ($startRow = 2; $startRow <= $highestRow; $startRow += $chunkSize) 
{ 

    $chunkFilter->setRows($startRow, $chunkSize); 
    $objPHPExcel  = $reader->load($file_path); 

    for($row = $startRow ; $row <= $startRow + $chunkSize; $row++)
    {
        $this->read_row = $objPHPExcel->getActiveSheet()->rangeToArray('A'.$row.':'.$highestColumn.$row, null, true, true, true);

        $this->read_row = end($this->read_row);         

        foreach($this->read_row as $column => $value)
        {
            $db_column_name = $this->_getDbColumnMap($column);
            if(!empty($db_column_name))
            {
                $this->new_data_row[$db_column_name] = $this->_getRowData($value, $column);
            }   

        }

        $this->read_row = null;
        $this->new_data_row['date_uploaded']    = date("Y-m-d H:i:s");
        $this->new_data_row['source_file_name'] = $file_name;
        $ipo_row  = new Model_UploadData_IPO();
        $ipo_row->create($this->new_data_row);
        $this->new_data_row = null;
        unset($ipo_row);

        gc_collect_cycles();

    }
    $objPHPExcel->disconnectWorksheets(); 
    unset($objPHPExcel);    
    gc_collect_cycles();

当我在取消设置 objPHPExcel 之前和之后测试内存使用情况时,没有内存增益,我真的很困惑,因为拆分成块似乎不允许我在每个块之后清除内存,并且使用量逐渐上升,并且限制设置为 250MB,它只允许我添加 ~500 条记录

【问题讨论】:

  • 这不是最后一个问题 =) 看看 stackoverflow.com/questions/6857075/problem-with-excell-export (吃 500MB)
  • 抱歉这里漏掉了一半。只允许我添加 ~500 条记录
  • Kasia:如果你犯了错误,你可以编辑你的问题
  • thx Mchl,我似乎不是唯一一个遇到这个问题的人:phpexcel.codeplex.com/discussions/267483 有完全相同的问题!
  • 我也遇到过 PHPExcel 在大文件上失败的问题。我最终决定使用 COM 接口直接与 Excel 对话。这很棘手,需要您在 Windows 上运行脚本并安装 Excel……但至少它可以工作。

标签: php memory phpexcel


【解决方案1】:

PHP excel 库is known to have these memory issues,我也有这个问题。对我有用的是这个建议(从上面的链接中尝试一下,有很好的建议如何减少内存使用):

$objReader = new PHPExcel_Reader_Excel5();
$objReader->setReadDataOnly(true); /* this */

但无论如何,内存需求很大,因为它们为每个单元格分配了大量内存(用于格式化等,即使不需要)。恐怕在他们发布新版本的库之前我们都束手无策。

【讨论】:

    【解决方案2】:

    好的,大家都知道trwtf是Excel,请问能不能把它转成CSV?

    我有我自己的 CSV 到 PHP 中的表格函数,这些函数用于导入非常大的文件,CSV 往往更容易处理,而且更不容易出现随机库问题。

    如果您确实需要这个一次性流程,或者可以很容易地从 XLS 转换为 CSV,请这样做,因为它会让您的生活更轻松(每次您坚持使用更简单、更标准的替代方案时;))。

    因此,对于将翻译糟糕透顶的 XLS 格式的 API,您可以使用以下 o/s 转换器之一 - 我每次都推荐使用 python,但嘿,您可以选择:

    http://www.oooninja.com/2008/02/batch-command-line-file-conversion-with.html

    http://code.google.com/p/jodconverter/wiki/FAQ

    基本上这个想法是一样的,你使用一个外部工具来获得一个可用的文件格式,然后你就从那里开始。

    我想我这里没有我的 csvtotable.php 脚本,但它很容易复制,你只需要一些基本工具,比如 csvtoarray 和 arraytoinsertstatements。

    GL ;)

    【讨论】:

    • 我很想只上传 CSV 文件,但不幸的是,这不是客户想要的。
    • 好吧,我也有办法解决这个问题……那公共汽车呢? - 不开玩笑,使用 OpenOffice API,它可以很容易地做到这一点 imo - 主帖中的链接
    • 在我上一份工作中,我还遇到了 PHPExcel 问题和大型 Excel 文件的内存问题。虽然我只是阅读它们,但我仍然遇到问题,因为我们的一些供应商正在上传 20MB 以上的文件。如果我没记错的话,我也使用 OpenOffice API 打开文件并将其转换为 CSV,然后使用新文件遍历并将记录插入到我的数据库中。我已经为我们的用户提供了 OpenOffice Calc 文件的上传功能,所以我已经有了代码。如果您使用 OpenOffice 完成这项工作,我们很乐意看到您的解决方案。
    猜你喜欢
    • 2012-08-28
    • 2011-12-12
    • 1970-01-01
    • 2014-07-16
    • 1970-01-01
    • 2018-01-26
    • 1970-01-01
    • 2012-04-15
    • 2015-06-14
    相关资源
    最近更新 更多