简体   繁体   English

PHPExcel ReadFilter类

[英]PHPExcel ReadFilter Class

I am attempting to use a ReadFilter with PHPExcel to only read in certain columns. 我试图将ReadFilter与PHPExcel一起使用以仅在某些列中读取。

I am using the example from their documentation: 我正在使用他们文档中的示例:

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

    public function __construct($startRow, $endRow, $columns) {
        $this->_startRow    = $startRow;
        $this->_endRow      = $endRow;
        $this->_columns     = $columns;
    }

    public function readCell($column, $row, $worksheetName = '') {
        if ($row >= $this->_startRow && $row <= $this->_endRow) {
            if (in_array($column,$this->_columns)) {
                return true;
            }
        }
        return false;
    }
}  

I am using an array called $importColsFilter which is shown below. 我正在使用一个名为$ importColsFilter的数组,如下所示。 I am passing this as the column for the ReadFilter. 我将其作为ReadFilter的列传递。

$importColsFilter  

Array (  
    [0] => A  
    [1] => B  
    [2] => C  
    [3] => H  
    [4] => I
    [5] => J
)  

$filterColumns = new columnFilter(2,8,$importColsFilter);
$objReader->setReadFilter($filterColumns);  
$sheetData = $objPHPExcel->getActiveSheet()->toArray(null,true,true,true);

When I grab the entire sheet ($sheetData), I was expecting to only get Columns A, B, C, H, I, and J. However, I am getting columns A through J as a range and anything in between that as seen with the array dump below. 当我拿起整个工作表($ sheetData)时,我期望只获得列A,B,C,H,I和J。但是,我得到的列A至J是一个范围,并且介于两者之间与下面的数组转储。

$sheetData

Array (  
    [A] => CellValue1  
    [B] => CellValue2
    [C] => CellValue3
    [D] => 
    [E] => 
    [F] => 
    [G] => 
    [H] => CellValue4
    [I] => CellValue5
    [J] => CellValue6
)  

The above looks to be the behavior of passing a range array to the filter instead of a normal array like so: new columnFilter(2,8,range('A','J')) It appears the filter works for grabbing the data, but it's dumping the columns into the array anyway with NULL value. 上面的代码看起来像是将范围数组传递给过滤器而不是像普通数组那样的行为: new columnFilter(2,8,range('A','J'))似乎过滤器可用于获取数据,但无论如何还是将NULL值将列转储到数组中。 Is this the expected behavior? 这是预期的行为吗? Can I just return the columns I want? 我可以只返回想要的列吗?

I was looking for a clean solution using the PHPExcel class. 我一直在寻找使用PHPExcel类的干净解决方案。 If there is no way there, I can just remove the array entries that are returned as NULL and dump it into another array. 如果没有办法,我可以删除以NULL返回的数组条目并将其转储到另一个数组中。 An example below: 下面的例子:

foreach(array_Keys($sheetData) as $sheetDataKey) {
    foreach($sheetData[$sheetDataKey] as $key => $value) {
        if(array_key_exists($key, $sheetData[$sheetDataKey]) && is_null($sheetData[$sheetDataKey][$key])) {
            unset($sheetData[$sheetDataKey][$key]);
        }
    }
}

The portion in the class that is checking for the column to be read is in the array passed to the function, that it would only return that column. 类中正在检查要读取的列的部分位于传递给该函数的数组中,即它将仅返回该列。 I wasn't expecting to see columns returned with a NULL value. 我没想到会看到以NULL值返回的列。 if (in_array($column,$this->_columns))

Is there anyway to do this with straight PHPExcel, or should I just pop the array entries that are NULL? 无论如何,可以使用直接的ExcelExcel来执行此操作,还是应该仅弹出NULL的数组条目?

Just because you're telling PHPExcel to leave a gap in the columns that it reads, doesn't mean that PHPExcel will shuffle all subsequent columns up to fill that gap.... it won't. 仅仅因为您在告诉PHPExcel在其读取的列中留有空白,并不意味着PHPExcel会重新整理所有后续列以填补该空白。 Using the read filter, you're telling the Reader not to read any data from columns D, E, F and G, and it doesn't.... but it won't move column H over to column D, I over to E, etc. either. 使用读取过滤器,您要告诉读取器不要从D,E,F和G列读取任何数据,并且不会....但是它将不会将H列移至D列,而是到E等。

Columns D, E, F and G can't "not exist", but when you use that read filter it means they won't contain any data, that the cells will be empty and not take up any memory. D,E,F和G列不能“不存在”,但是当您使用该读取过滤器时,这意味着它们将不包含任何数据,这些单元将为空并且不占用任何内存。

If you want to shuffle up H to D, I to E, etc then you need to delete those columns completely using the worksheet's removeColumn() method. 如果您想将H换为D,将I换为E,等等,则需要使用工作表的removeColumn()方法完全删除这些列。

If you want to remove them from a row in $sheetData , then the easiest is to walk the rows using array_intersect_key() to eliminate those columns 如果要从$sheetData的一行中删除它们,那么最简单的方法是使用array_intersect_key()遍历这些行以消除那些列

I made PHPExcelFormatter if I needed to get only certain columns from excel file. 如果我只需要从excel文件中获取某些列,则可以使用PHPExcelFormatter Unfortunately it dosen't support $startRow and $endRow , but it should be quite easy to add it. 不幸的是,它不支持$startRow$endRow ,但是添加起来应该很容易。

It's basically like your columnFilter . 基本上就像您的columnFilter It outputs array with your own keys. 它使用您自己的键输出array

It takes array as in demo $formatterColumns . 它像演示$formatterColumns那样使用array For example, to skip DG. 例如,跳过DG。

<?php

// Load file
$formatter = new PHPExcelFormatter('example1.xls');

// Output columns array (document dosen't have column names on first row)
$formatterColumns = array(
    0 => 'A',
    1 => 'B',
    2 => 'C',
    7 => 'H',
    8 => 'I',
    9 => 'J'
) 

// Set our columns
$formatter->setFormatterColumns($formatterColumns);

// Output as array
$output = $formatter->output('a');

// Print array
echo '<pre>'.print_r($output, true).'</pre>';

?>

Output would be: 输出为:

Array (  
    [A] => CellValue1  
    [B] => CellValue2
    [C] => CellValue3
    [H] => CellValue4
    [I] => CellValue5
    [J] => CellValue6
)  

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM