【问题标题】:PHPExcel - Using example read fiterPHPExcel - 使用示例读取过滤器
【发布时间】:2013-01-01 20:18:33
【问题描述】:

我刚刚开始使用 PHPExcel。我的非常大的电子表格无法全部加载到内存中(内存故障)。为了只加载我需要的工作表部分,我正在尝试使用文档中提供的 MyReadFilter 代码,但代码有点高,我希望有人能帮助我理解它。

来自 PHPExcel 文档,函数如下:

class ReadFilter implements PHPExcel_Reader_IReadFilter 
    { 
    private $_startRow = 0; 
    private $_endRow   = 0; 
    private $_columns  = array(); 

    /**  Get the list of rows and columns to read  */ 
    public function __construct($startRow, $endRow, $columns) { 
        $this->_startRow = $startRow; 
        $this->_endRow   = $endRow; 
        $this->_columns  = $columns; 
        } 

    public function readCell($column, $row, $worksheetName = '') { 
    // Only read the rows and columns that were configured 
    if ($row >= $this->_startRow && $row <= $this->_endRow) { 
        if (in_array($column,$this->_columns)) { 
        return true; 
        } 
    } 
    return false; 
    } 
}   

我正在使用以下几行来调用 PHPExcel

//  Get the selected Excel file, passed from form
$testFile = $_FILES['upload_test']['tmp_name'];     
//  Identify the file type of the selected file
$inputFileType = PHPExcel_IOFactory::identify($testFile);
//  Create a reader object of the correct file type 
$objReader = PHPExcel_IOFactory::createReader($inputFileType);
//  Instantiate the filter class and apply it to the reader object
$filterSubset = new ReadFilter(1,1000,range('A','Z'));
$objReader->setReadFilter($filterSubset);       
//  Load the selected file into the reader
$objWorkbook = $objReader->load($testFile); 

我正在使用以下语法从生成的工作表对象中检索数据:

$someValue= $objWorkbook->getSheet($idx)->getCell('B11')->getCalculatedValue();

我确信我在进行过程中还会有其他问题,但我的第一个问题是关于调用该函数。如果我将上面的行从:

$filterSubset = new ReadFilter(1,1000,range('A','Z'));

到:

$filterSubset = new ReadFilter(1,1000,range('A','AA'));  //Last column changed

整个读取失败。我实际上只需要 B 列的计算值,但该列的引用远至 AS 列,所以我也需要阅读它们。有人可以告诉我如何使用这个函数来阅读过去的 Z 列,或者修改它吗?理想情况下,我只想阅读从 B 到 AS 分布的大约十几列的内容,但我也无法弄清楚。

非常感谢您的帮助。

【问题讨论】:

  • 我知道这不是您正在寻找的答案,但是您能否将单元格 B 中的这些计算值复制到新列中,“粘贴为值”,然后仅将该列用于您的程序?粘贴为值将为您提供复制单元格的值,而无需计算开销。
  • 在深入探讨之前,您正在使用的 excel 文件是否对于内存来说太大了,或者只是稍微太大了?如果您只需要更多的内存并且您知道您的硬件可以处理它,您可以使用ini_set('memory_limit', '128M');。尽管如果您期望更大的文件,使用此读取过滤器将是您最稳定的路线。
  • 感谢双方。我正在寻找更强大的解决方案(大小不确定,有些文件可能会破坏它。)

标签: php filter spreadsheet phpexcel


【解决方案1】:

range('A','AA'); 无效尝试创建自己的自定义范围

例子

echo "<pre>";
print_r(xrange('AA', 'ZZ'));

使用的功能

function xrange($start, $end, $limit = 1000) {
    $l = array();
    while ($start !== $end && count($l) < $limit) {
        $l[] = $start;
        $start ++;
    }
    $l[] = $end;
    return $l;
}

See Live Demo

【讨论】:

  • 感谢您的提示和演示。今晚我会试试看。
  • 简化比较: $endTest = $end; $endTest++; while ($start !== $endTest) { 以消除更昂贵的 strcmp() 函数和比较
  • Baba,在对你的函数进行了胡思乱想之后,我终于想到我可以只创建一个只包含我需要的列的数组(加上 A 列,出于某种原因,这是必需的)。像魅力一样工作。再次非常感谢您告诉我问题所在并为我指明了正确的方向。
【解决方案2】:

range('A','AA) 不是有效范围...。 PHP 的 range 函数不假定 AA 跟随 Z。尝试使用列号,使用 PHPExcel 的 columnIndexFromString() 和 stringFromColumnIndex() 静态PHPExcel_Cell 类中的方法将 27 转换为 AA,反之亦然(注意基值 0 或 1)。

【讨论】:

  • 马克,在你和爸爸向我解释了问题所在之后,我想出了一个更简单的解决方案(见上面的回复)。但是我仍然会使用您推荐的那些工具来熟悉它们。再次感谢您抽出宝贵时间回复。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-22
  • 1970-01-01
  • 2011-11-10
  • 2015-05-15
  • 1970-01-01
  • 2019-07-04
相关资源
最近更新 更多