From 98d1782bbb4e392d9cd0aab7f896e7c3722083c4 Mon Sep 17 00:00:00 2001 From: phinor <20402493+phinor@users.noreply.github.com> Date: Mon, 15 Apr 2019 21:40:20 +0200 Subject: [PATCH] Xls(x) Readers now respect the readBlankCells setting. (#835) * Prevented reading of blank cells. The "readEmptyCells" attribute is ignored when reading spreadsheets, resulting in memory bloat. * Included a test file for Unit Testing A file that contains 100 referenced cells, one of which contains data. * New test file for reading in empty cells * Added test for reading in a blank cell * Updated CHANGELOG * Changed "s to 's Change required for code style compliance * Further Code Style Changes Removed spaces after variable, before array indices. * Further Code Style Changes * Further Code Style Changes Removed additional spaces. * Updated reader and tests. --- CHANGELOG.md | 1 + src/PhpSpreadsheet/Reader/Xlsx.php | 59 ++++++++++--------- .../Functional/ReadBlankCellsTest.php | 50 ++++++++++++++++ 3 files changed, 82 insertions(+), 28 deletions(-) create mode 100644 tests/PhpSpreadsheetTests/Functional/ReadBlankCellsTest.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 499ae3d2..06f1ef66 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,7 @@ and this project adheres to [Semantic Versioning](https://semver.org). - Improve XLSX parsing speed if no readFilter is applied - [#772](https://github.com/PHPOffice/PhpSpreadsheet/issues/772) - Fix column names if read filter calls in XLSX reader skip columns - [#777](https://github.com/PHPOffice/PhpSpreadsheet/pull/777) +- XLSX reader can now ignore blank cells, using the setReadEmptyCells(false) method. - [#810](https://github.com/PHPOffice/PhpSpreadsheet/issues/810) - Fix LOOKUP function which was breaking on edge cases - [#796](https://github.com/PHPOffice/PhpSpreadsheet/issues/796) - Fix VLOOKUP with exact matches - [#809](https://github.com/PHPOffice/PhpSpreadsheet/pull/809) - Support COUNTIFS multiple arguments - [#830](https://github.com/PHPOffice/PhpSpreadsheet/pull/830) diff --git a/src/PhpSpreadsheet/Reader/Xlsx.php b/src/PhpSpreadsheet/Reader/Xlsx.php index 8c68a1a7..cbf3fedc 100644 --- a/src/PhpSpreadsheet/Reader/Xlsx.php +++ b/src/PhpSpreadsheet/Reader/Xlsx.php @@ -972,38 +972,41 @@ class Xlsx extends BaseReader break; } - // Check for numeric values - if (is_numeric($value) && $cellDataType != 's') { - if ($value == (int) $value) { - $value = (int) $value; - } elseif ($value == (float) $value) { - $value = (float) $value; - } elseif ($value == (float) $value) { - $value = (float) $value; + // read empty cells or the cells are not empty + if ($this->readEmptyCells || ($value !== null && $value !== '')) { + // Check for numeric values + if (is_numeric($value) && $cellDataType != 's') { + if ($value == (int) $value) { + $value = (int) $value; + } elseif ($value == (float) $value) { + $value = (float) $value; + } elseif ($value == (float) $value) { + $value = (float) $value; + } } - } - // Rich text? - if ($value instanceof RichText && $this->readDataOnly) { - $value = $value->getPlainText(); - } + // Rich text? + if ($value instanceof RichText && $this->readDataOnly) { + $value = $value->getPlainText(); + } - $cell = $docSheet->getCell($r); - // Assign value - if ($cellDataType != '') { - $cell->setValueExplicit($value, $cellDataType); - } else { - $cell->setValue($value); - } - if ($calculatedValue !== null) { - $cell->setCalculatedValue($calculatedValue); - } + $cell = $docSheet->getCell($r); + // Assign value + if ($cellDataType != '') { + $cell->setValueExplicit($value, $cellDataType); + } else { + $cell->setValue($value); + } + if ($calculatedValue !== null) { + $cell->setCalculatedValue($calculatedValue); + } - // Style information? - if ($c['s'] && !$this->readDataOnly) { - // no style index means 0, it seems - $cell->setXfIndex(isset($styles[(int) ($c['s'])]) ? - (int) ($c['s']) : 0); + // Style information? + if ($c['s'] && !$this->readDataOnly) { + // no style index means 0, it seems + $cell->setXfIndex(isset($styles[(int) ($c['s'])]) ? + (int) ($c['s']) : 0); + } } $rowIndex += 1; } diff --git a/tests/PhpSpreadsheetTests/Functional/ReadBlankCellsTest.php b/tests/PhpSpreadsheetTests/Functional/ReadBlankCellsTest.php new file mode 100644 index 00000000..846c3742 --- /dev/null +++ b/tests/PhpSpreadsheetTests/Functional/ReadBlankCellsTest.php @@ -0,0 +1,50 @@ +getActiveSheet()->getCell('B2')->setValue(''); + $spreadsheet->getActiveSheet()->getCell('C1')->setValue('C1'); + $spreadsheet->getActiveSheet()->getCell('C3')->setValue('C3'); + + $reloadedSpreadsheet = $this->writeAndReload($spreadsheet, $format); + $this->assertTrue($reloadedSpreadsheet->getActiveSheet()->getCellCollection()->has('B2')); + $this->assertFalse($reloadedSpreadsheet->getActiveSheet()->getCellCollection()->has('C2')); + $this->assertTrue($reloadedSpreadsheet->getActiveSheet()->getCellCollection()->has('C3')); + + $reloadedSpreadsheet = $this->writeAndReload($spreadsheet, $format, function($reader) { + $reader->setReadEmptyCells(false); + }); + $this->assertFalse($reloadedSpreadsheet->getActiveSheet()->getCellCollection()->has('B2')); + $this->assertFalse($reloadedSpreadsheet->getActiveSheet()->getCellCollection()->has('C2')); + $this->assertTrue($reloadedSpreadsheet->getActiveSheet()->getCellCollection()->has('C3')); + } + +}