update xlsx reader

This commit is contained in:
Salavat Salakhutdinov 2020-10-30 18:47:08 +03:00
parent 7f26167be8
commit f8baef148f
3 changed files with 44 additions and 2 deletions

View File

@ -23,6 +23,7 @@ class CellValueFormatter
/** Definition of XML nodes names used to parse data */
const XML_NODE_VALUE = 'v';
const XML_NODE_FORMULA = 'f';
const XML_NODE_INLINE_STRING_VALUE = 't';
/** Definition of XML attributes used to parse data */
@ -107,6 +108,21 @@ class CellValueFormatter
}
}
/**
* Returns the cell formula associated to the given XML node.
*
* @param \DOMNode $node
* @return string The formula associated with the cell
*/
public function extractNodeFormula($node)
{
// for cell types having a "f" tag containing the formula.
// if not, the returned formula should be empty string.
$vNode = $node->getElementsByTagName(self::XML_NODE_FORMULA)->item(0);
return ($vNode !== null) ? $vNode->nodeValue : '';
}
/**
* Returns the cell's string value from a node's nested value node
*

View File

@ -359,7 +359,9 @@ class RowIterator implements IteratorInterface
{
try {
$cellValue = $this->cellValueFormatter->extractAndFormatNodeValue($node);
$cellFormula = $this->cellValueFormatter->extractNodeFormula($node);
$cell = $this->entityFactory->createCell($cellValue);
$cell->setFormula($cellFormula);
} catch (InvalidValueException $exception) {
$cell = $this->entityFactory->createCell($exception->getInvalidValue());
$cell->setType(Cell::TYPE_ERROR);

View File

@ -574,6 +574,29 @@ class ReaderTest extends TestCase
$this->assertEquals($expectedRows, $allRows);
}
/**
* @return void
*/
public function testReadShouldReadFormulas()
{
$allRows = $this->getAllRowsForFile('sheet_with_formulas.xlsx', false, false, false);
$expectedRows = [
['', '', '', ''],
['', '', 'A2+B2', 'SUM(A:A)'],
['', '', 'A3+B3', 'SUM(B:B)'],
];
$rowsWithFormulas = array_map(function($row) {
$cells = $row->getCells();
return array_map(function($cell) {
return $cell->getFormula();
}, $cells);
}, $allRows);
$this->assertEquals($expectedRows, $rowsWithFormulas);
}
/**
* @return void
*/
@ -703,9 +726,10 @@ class ReaderTest extends TestCase
* @param string $fileName
* @param bool $shouldFormatDates
* @param bool $shouldPreserveEmptyRows
* @param bool $shouldConvertToArray
* @return array All the read rows the given file
*/
private function getAllRowsForFile($fileName, $shouldFormatDates = false, $shouldPreserveEmptyRows = false)
private function getAllRowsForFile($fileName, $shouldFormatDates = false, $shouldPreserveEmptyRows = false, $shouldConvertToArray = true)
{
$allRows = [];
$resourcePath = $this->getResourcePath($fileName);
@ -717,7 +741,7 @@ class ReaderTest extends TestCase
foreach ($reader->getSheetIterator() as $sheetIndex => $sheet) {
foreach ($sheet->getRowIterator() as $rowIndex => $row) {
$allRows[] = $row->toArray();
$allRows[] = $shouldConvertToArray ? $row->toArray() : $row;
}
}