Skip to content
This repository was archived by the owner on May 26, 2022. It is now read-only.

Commit 7964dad

Browse files
committed
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.
1 parent eb88bb4 commit 7964dad

File tree

5 files changed

+53
-0
lines changed

5 files changed

+53
-0
lines changed

src/Spout/Common/Entity/Cell.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,14 @@ public function getValue()
9191
return !$this->isError() ? $this->value : null;
9292
}
9393

94+
/**
95+
* @return mixed
96+
*/
97+
public function getValueEvenIfError()
98+
{
99+
return $this->value;
100+
}
101+
94102
/**
95103
* @param Style|null $style
96104
*/

src/Spout/Writer/ODS/Manager/WorksheetManager.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,11 @@ private function getCellXML(Cell $cell, $styleIndex, $numTimesValueRepeated)
204204
$data .= ' office:value-type="float" calcext:value-type="float" office:value="' . $cell->getValue() . '">';
205205
$data .= '<text:p>' . $cell->getValue() . '</text:p>';
206206
$data .= '</table:table-cell>';
207+
} elseif ($cell->isError() && is_string($cell->getValueEvenIfError())) {
208+
// only writes the error value if it's a string
209+
$data .= ' office:value-type="string" calcext:value-type="error" office:value="">';
210+
$data .= '<text:p>' . $cell->getValueEvenIfError() . '</text:p>';
211+
$data .= '</table:table-cell>';
207212
} elseif ($cell->isEmpty()) {
208213
$data .= '/>';
209214
} else {

src/Spout/Writer/XLSX/Manager/WorksheetManager.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,9 @@ private function getCellXML($rowIndexOneBased, $columnIndexZeroBased, Cell $cell
218218
$cellXML .= ' t="b"><v>' . (int) ($cell->getValue()) . '</v></c>';
219219
} elseif ($cell->isNumeric()) {
220220
$cellXML .= '><v>' . $cell->getValue() . '</v></c>';
221+
} elseif ($cell->isError() && is_string($cell->getValueEvenIfError())) {
222+
// only writes the error value if it's a string
223+
$cellXML .= ' t="e"><v>' . $cell->getValueEvenIfError() . '</v></c>';
221224
} elseif ($cell->isEmpty()) {
222225
if ($this->styleManager->shouldApplyStyleOnEmptyCell($styleId)) {
223226
$cellXML .= '/>';

tests/Spout/Writer/ODS/WriterTest.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace Box\Spout\Writer\ODS;
44

5+
use Box\Spout\Common\Entity\Cell;
56
use Box\Spout\Common\Entity\Row;
67
use Box\Spout\Common\Exception\InvalidArgumentException;
78
use Box\Spout\Common\Exception\IOException;
@@ -321,6 +322,24 @@ public function testAddRowShouldUseNumberColumnsRepeatedForRepeatedValues($dataR
321322
}
322323
}
323324

325+
/**
326+
* @return void
327+
*/
328+
public function testAddRowShouldSupportCellInError()
329+
{
330+
$fileName = 'test_add_row_should_support_cell_in_error.ods';
331+
332+
$cell = WriterEntityFactory::createCell('#DIV/0');
333+
$cell->setType(Cell::TYPE_ERROR);
334+
335+
$row = WriterEntityFactory::createRow([$cell]);
336+
337+
$this->writeToODSFile([$row], $fileName);
338+
339+
$this->assertValueWasWritten($fileName, 'calcext:value-type="error"');
340+
$this->assertValueWasWritten($fileName, '<text:p>#DIV/0</text:p>');
341+
}
342+
324343
/**
325344
* @return void
326345
*/

tests/Spout/Writer/XLSX/WriterTest.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace Box\Spout\Writer\XLSX;
44

5+
use Box\Spout\Common\Entity\Cell;
56
use Box\Spout\Common\Entity\Row;
67
use Box\Spout\Common\Exception\InvalidArgumentException;
78
use Box\Spout\Common\Exception\IOException;
@@ -375,6 +376,23 @@ public function testAddRowShouldSupportMultipleTypesOfData()
375376
$this->assertInlineDataWasWrittenToSheet($fileName, 1, 10.2);
376377
}
377378

379+
/**
380+
* @return void
381+
*/
382+
public function testAddRowShouldSupportCellInError()
383+
{
384+
$fileName = 'test_add_row_should_support_cell_in_error.xlsx';
385+
386+
$cell = WriterEntityFactory::createCell('#DIV/0');
387+
$cell->setType(Cell::TYPE_ERROR);
388+
389+
$row = WriterEntityFactory::createRow([$cell]);
390+
391+
$this->writeToXLSXFile([$row], $fileName);
392+
393+
$this->assertInlineDataWasWrittenToSheet($fileName, 1, 't="e"><v>#DIV/0</v>');
394+
}
395+
378396
/**
379397
* @return void
380398
*/

0 commit comments

Comments
 (0)