Add support for missing cell reference

When describing a cell, the cell reference (r="A1") is optional.
When not present, we should just increment the index of the last processed row.
This commit is contained in:
Adrien Loison 2016-07-11 16:38:41 +02:00
parent b02d13cd40
commit 0b5d848311
3 changed files with 39 additions and 2 deletions

View File

@ -55,6 +55,9 @@ class RowIterator implements IteratorInterface
/** @var int The number of columns the sheet has (0 meaning undefined) */
protected $numColumns = 0;
/** @var int Last column index processed (zero-based) */
protected $lastColumnIndexProcessed = -1;
/**
* @param string $filePath Path of the XLSX file being read
* @param string $sheetDataXMLFilePath Path of the sheet data XML file as in [Content_Types].xml
@ -144,6 +147,9 @@ class RowIterator implements IteratorInterface
} else if ($this->xmlReader->isPositionedOnStartingNode(self::XML_NODE_ROW)) {
// Start of the row description
// Reset index of the last processed column
$this->lastColumnIndexProcessed = -1;
// Read spans info if present
$numberOfColumnsForRow = $this->numColumns;
$spans = $this->xmlReader->getAttribute(self::XML_ATTRIBUTE_SPANS); // returns '1:5' for instance
@ -155,12 +161,13 @@ class RowIterator implements IteratorInterface
} else if ($this->xmlReader->isPositionedOnStartingNode(self::XML_NODE_CELL)) {
// Start of a cell description
$currentCellIndex = $this->xmlReader->getAttribute(self::XML_ATTRIBUTE_CELL_INDEX);
$currentColumnIndex = CellHelper::getColumnIndexFromCellIndex($currentCellIndex);
$currentColumnIndex = $this->getCellIndex($this->xmlReader);
$node = $this->xmlReader->expand();
$rowData[$currentColumnIndex] = $this->getCellValue($node);
$this->lastColumnIndexProcessed = $currentColumnIndex;
} else if ($this->xmlReader->isPositionedOnEndingNode(self::XML_NODE_ROW)) {
// End of the row description
// If needed, we fill the empty cells
@ -182,6 +189,21 @@ class RowIterator implements IteratorInterface
$this->rowDataBuffer = $rowData;
}
/**
* @param \Box\Spout\Reader\Wrapper\XMLReader $xmlReader XMLReader object, positioned on a "<c>" tag
* @return int
* @throws \Box\Spout\Common\Exception\InvalidArgumentException When the given cell index is invalid
*/
protected function getCellIndex($xmlReader)
{
// Get "r" attribute if present (from something like <c r="A1"...>
$currentCellIndex = $xmlReader->getAttribute(self::XML_ATTRIBUTE_CELL_INDEX);
return ($currentCellIndex !== null) ?
CellHelper::getColumnIndexFromCellIndex($currentCellIndex) :
$this->lastColumnIndexProcessed + 1;
}
/**
* Returns the (unescaped) correctly marshalled, cell value associated to the given XML node.
*

View File

@ -140,6 +140,21 @@ class ReaderTest extends \PHPUnit_Framework_TestCase
$this->assertEquals($expectedRows, $allRows);
}
/**
* @return void
*/
public function testReadShouldSupportFilesWithoutCellReference()
{
// file where the cell definition does not have a "r" attribute
// as in <c r="A1">...</c>
$allRows = $this->getAllRowsForFile('sheet_with_missing_cell_reference.xlsx');
$expectedRows = [
['s1--A1'],
];
$this->assertEquals($expectedRows, $allRows);
}
/**
* @return void
*/