Как читать пустые ячейки в PHPExcel, не пропуская значения?

Мне нужна ваша помощь, чтобы решить одну проблему.

Я пытался найти ответ, но не нашел. Я использую PHPExcel 1.8.0 для чтения данных из файла excel. И я использую ReadFilter для чтения определенных столбцов.

Основной код PHP.

        $price = UPLOAD_DIR . $price;

        $file_type = PHPExcel_IOFactory::identify($price);

        $filter = new ShipperReadFilter();

        $filter->getShipperSettings($shipper);          

        $reader = PHPExcel_IOFactory::createReader($file_type)->setReadDataOnly(true)->setReadFilter($filter)->load($price);

        $worksheet = $reader->getActiveSheet();

        $col_number = PHPExcel_Cell::columnIndexFromString($worksheet->getHighestDataColumn());

        $data = array();

        foreach ($worksheet->getRowIterator($filter->getStartRow()) as $row) {

            $cellIterator = $row->getCellIterator();

            $item = array();

            foreach ($cellIterator as $cell) {
                // May be PROBLEM is Here?
                array_push($item, $cell->getCalculatedValue());
            }

            array_push($data, $item);
        }           

        var_dump($data);

Код ReadFilter.

class ShipperReadFilter implements PHPExcel_Reader_IReadFilter {

public $valid_columns = array();

public $start_row;

public function setValidColumns ($columns) {
    $this->valid_columns = $columns;
}

public function getShipperSettings ($shipper) {

    switch ($shipper) {

        // Shipper 1
        case 1 : 
            $this->setValidColumns(array('A', 'D', 'F'));
            $this->start_row = 4;
            break;

        // Shipper 2
        case 2 :
            $this->setValidColumns(array('A', 'R', 'T'));
            $this->start_row = 7;
            break;

        // Shipper 3
        case 3 :
            $this->setValidColumns(array('H', 'I', 'J'));
            $this->start_row = 14;
            break;
    }
}

public function getStartRow () {
    return $this->start_row;
}

public function readCell($column, $row, $worksheetName = '') {

    if (in_array($column, $this->valid_columns)) {
        return true;
    }
    return false;
}   
}   

Результат

array(3501) { 
   [0]=> array(2) { 
       [0]=> string(11) "01-00018239" 
       [1]=> float(2493) 
}

Но мне это нужно

array(3501) { 
[0]=> array(3) { 
    [0]=> string(11) "01-00018239" 
    [1]=> float(2493) 
    [2]=> null // or '', or 0
}

Есть ли правильный способ решить эту проблему? Спасибо.


person Community    schedule 13.03.2015    source источник


Ответы (1)


По умолчанию итератор ячеек будет перебирать только те ячейки, которые действительно существуют.

$cellIterator = $row->getCellIterator();
$cellIterator->setIterateOnlyExistingCells(false);

$item = array();
foreach ($cellIterator as $cell) {
    array_push($item, $cell->getCalculatedValue());
}

Однако, если все, что вы делаете, это создаете массив вычисляемых значений для каждой строки, то вы можете обнаружить, что использование метода rangeToArray() рабочего листа более эффективно.

ИЗМЕНИТЬ

Чтобы получить только ячейки, соответствующие вашему списку столбцов фильтра чтения:

foreach ($cellIterator as $cell) {
    $item[$cell->getColumn()] = $cell->getCalculatedValue();
}
$item = array_intersect_key($item, array_flip($filter->valid_columns));

or

foreach ($cellIterator as $cell) {
    if(in_array($cell->getColumn(), $filter->valid_columns)) {
        array_push($item, $cell->getCalculatedValue());
    }
}
person Mark Baker    schedule 13.03.2015
comment
Спасибо, Марк. Этот метод работает, но теперь ReadFilter не работает - читает все столбцы, а я хочу прочитать только 3 столбца... Можете помочь? - person ; 13.03.2015
comment
Фильтр чтения не считывает ячейки для тех столбцов, которые не входят в определенный вами набор..... если вы попытаетесь получить значение для столбца, который не был прочитан, вы получите NULL, потому что ячейка не не существует.... но итератор ячеек не знает, должен ли существовать столбец из-за фильтра или нет.... он будет либо перебирать только существующие ячейки, либо перебирать все ячейки - person Mark Baker; 13.03.2015
comment
Если вы строите свой массив ячеек как ассоциативный массив с идентификатором столбца в качестве индекса; затем сделайте array_intersect_keys со списком столбцов для вашего грузоотправителя, тогда у вас будут только эти столбцы в массиве - person Mark Baker; 13.03.2015