From 7964dadc2128f3a00ffa393395b618ea115c8032 Mon Sep 17 00:00:00 2001 From: Adrien Loison Date: Sat, 16 Nov 2019 11:54:16 +0100 Subject: [PATCH] Add support for cells in error when writing XLSX and ODS When appending data to an existing sheet, it was possible to get cells in error when reading (DIV/0 for instance). When trying to write them back, `addRow` would throw because `Cell`s in error were not supported by the writers. --- src/Spout/Common/Entity/Cell.php | 8 ++++++++ .../Writer/ODS/Manager/WorksheetManager.php | 5 +++++ .../Writer/XLSX/Manager/WorksheetManager.php | 3 +++ tests/Spout/Writer/ODS/WriterTest.php | 19 +++++++++++++++++++ tests/Spout/Writer/XLSX/WriterTest.php | 18 ++++++++++++++++++ 5 files changed, 53 insertions(+) diff --git a/src/Spout/Common/Entity/Cell.php b/src/Spout/Common/Entity/Cell.php index bd7a730..c1de389 100644 --- a/src/Spout/Common/Entity/Cell.php +++ b/src/Spout/Common/Entity/Cell.php @@ -91,6 +91,14 @@ class Cell return !$this->isError() ? $this->value : null; } + /** + * @return mixed + */ + public function getValueEvenIfError() + { + return $this->value; + } + /** * @param Style|null $style */ diff --git a/src/Spout/Writer/ODS/Manager/WorksheetManager.php b/src/Spout/Writer/ODS/Manager/WorksheetManager.php index 6392259..4dfe9c8 100644 --- a/src/Spout/Writer/ODS/Manager/WorksheetManager.php +++ b/src/Spout/Writer/ODS/Manager/WorksheetManager.php @@ -204,6 +204,11 @@ class WorksheetManager implements WorksheetManagerInterface $data .= ' office:value-type="float" calcext:value-type="float" office:value="' . $cell->getValue() . '">'; $data .= '' . $cell->getValue() . ''; $data .= ''; + } elseif ($cell->isError() && is_string($cell->getValueEvenIfError())) { + // only writes the error value if it's a string + $data .= ' office:value-type="string" calcext:value-type="error" office:value="">'; + $data .= '' . $cell->getValueEvenIfError() . ''; + $data .= ''; } elseif ($cell->isEmpty()) { $data .= '/>'; } else { diff --git a/src/Spout/Writer/XLSX/Manager/WorksheetManager.php b/src/Spout/Writer/XLSX/Manager/WorksheetManager.php index d4e65e2..741d0aa 100644 --- a/src/Spout/Writer/XLSX/Manager/WorksheetManager.php +++ b/src/Spout/Writer/XLSX/Manager/WorksheetManager.php @@ -218,6 +218,9 @@ EOD; $cellXML .= ' t="b">' . (int) ($cell->getValue()) . ''; } elseif ($cell->isNumeric()) { $cellXML .= '>' . $cell->getValue() . ''; + } elseif ($cell->isError() && is_string($cell->getValueEvenIfError())) { + // only writes the error value if it's a string + $cellXML .= ' t="e">' . $cell->getValueEvenIfError() . ''; } elseif ($cell->isEmpty()) { if ($this->styleManager->shouldApplyStyleOnEmptyCell($styleId)) { $cellXML .= '/>'; diff --git a/tests/Spout/Writer/ODS/WriterTest.php b/tests/Spout/Writer/ODS/WriterTest.php index 05c4930..b30a8f6 100644 --- a/tests/Spout/Writer/ODS/WriterTest.php +++ b/tests/Spout/Writer/ODS/WriterTest.php @@ -2,6 +2,7 @@ namespace Box\Spout\Writer\ODS; +use Box\Spout\Common\Entity\Cell; use Box\Spout\Common\Entity\Row; use Box\Spout\Common\Exception\InvalidArgumentException; use Box\Spout\Common\Exception\IOException; @@ -321,6 +322,24 @@ class WriterTest extends TestCase } } + /** + * @return void + */ + public function testAddRowShouldSupportCellInError() + { + $fileName = 'test_add_row_should_support_cell_in_error.ods'; + + $cell = WriterEntityFactory::createCell('#DIV/0'); + $cell->setType(Cell::TYPE_ERROR); + + $row = WriterEntityFactory::createRow([$cell]); + + $this->writeToODSFile([$row], $fileName); + + $this->assertValueWasWritten($fileName, 'calcext:value-type="error"'); + $this->assertValueWasWritten($fileName, '#DIV/0'); + } + /** * @return void */ diff --git a/tests/Spout/Writer/XLSX/WriterTest.php b/tests/Spout/Writer/XLSX/WriterTest.php index d8a4768..15cc4e4 100644 --- a/tests/Spout/Writer/XLSX/WriterTest.php +++ b/tests/Spout/Writer/XLSX/WriterTest.php @@ -2,6 +2,7 @@ namespace Box\Spout\Writer\XLSX; +use Box\Spout\Common\Entity\Cell; use Box\Spout\Common\Entity\Row; use Box\Spout\Common\Exception\InvalidArgumentException; use Box\Spout\Common\Exception\IOException; @@ -375,6 +376,23 @@ class WriterTest extends TestCase $this->assertInlineDataWasWrittenToSheet($fileName, 1, 10.2); } + /** + * @return void + */ + public function testAddRowShouldSupportCellInError() + { + $fileName = 'test_add_row_should_support_cell_in_error.xlsx'; + + $cell = WriterEntityFactory::createCell('#DIV/0'); + $cell->setType(Cell::TYPE_ERROR); + + $row = WriterEntityFactory::createRow([$cell]); + + $this->writeToXLSXFile([$row], $fileName); + + $this->assertInlineDataWasWrittenToSheet($fileName, 1, 't="e">#DIV/0'); + } + /** * @return void */