2015-03-13 43 views
2

我需要你的帮助来解决一个问题。如何在不跳过值的情况下读取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 
} 

有没有办法解决这个问题的正确方法?谢谢。

回答

2

默认情况下,电池迭代器将只遍历实际存在

$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)); 

foreach ($cellIterator as $cell) { 
    if(in_array($cell->getColumn(), $filter->valid_columns)) { 
     array_push($item, $cell->getCalculatedValue()); 
    } 
} 
+0

谢谢你,马克。此方法可行,但现在ReadFilter不起作用 - 读取所有列,但我只想读取3列...您能帮忙吗? – xormax666 2015-03-13 09:37:54

+0

读取过滤器不读取定义范围之外的那些列的单元格.....如果您尝试为未读取的列获取值,您将获得NULL,因为单元格不存在....但单元格迭代器不知道是否应该存在一列,因为是否有过滤器......它将只迭代存在的单元格,或迭代所有单元格 – 2015-03-13 09:40:54

+0

如果构建单元格数组作为关联数组,列ID作为索引;然后用你的托运人的列表做一个array_intersect_keys,那么你将只有数组中的那些列 – 2015-03-13 09:45:15

相关问题