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.
This commit is contained in:
phinor 2019-04-15 21:40:20 +02:00 committed by Mark Baker
parent 15abdf43ad
commit 98d1782bbb
3 changed files with 82 additions and 28 deletions

View File

@ -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) - 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) - 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 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) - 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) - Support COUNTIFS multiple arguments - [#830](https://github.com/PHPOffice/PhpSpreadsheet/pull/830)

View File

@ -972,38 +972,41 @@ class Xlsx extends BaseReader
break; break;
} }
// Check for numeric values // read empty cells or the cells are not empty
if (is_numeric($value) && $cellDataType != 's') { if ($this->readEmptyCells || ($value !== null && $value !== '')) {
if ($value == (int) $value) { // Check for numeric values
$value = (int) $value; if (is_numeric($value) && $cellDataType != 's') {
} elseif ($value == (float) $value) { if ($value == (int) $value) {
$value = (float) $value; $value = (int) $value;
} elseif ($value == (float) $value) { } elseif ($value == (float) $value) {
$value = (float) $value; $value = (float) $value;
} elseif ($value == (float) $value) {
$value = (float) $value;
}
} }
}
// Rich text? // Rich text?
if ($value instanceof RichText && $this->readDataOnly) { if ($value instanceof RichText && $this->readDataOnly) {
$value = $value->getPlainText(); $value = $value->getPlainText();
} }
$cell = $docSheet->getCell($r); $cell = $docSheet->getCell($r);
// Assign value // Assign value
if ($cellDataType != '') { if ($cellDataType != '') {
$cell->setValueExplicit($value, $cellDataType); $cell->setValueExplicit($value, $cellDataType);
} else { } else {
$cell->setValue($value); $cell->setValue($value);
} }
if ($calculatedValue !== null) { if ($calculatedValue !== null) {
$cell->setCalculatedValue($calculatedValue); $cell->setCalculatedValue($calculatedValue);
} }
// Style information? // Style information?
if ($c['s'] && !$this->readDataOnly) { if ($c['s'] && !$this->readDataOnly) {
// no style index means 0, it seems // no style index means 0, it seems
$cell->setXfIndex(isset($styles[(int) ($c['s'])]) ? $cell->setXfIndex(isset($styles[(int) ($c['s'])]) ?
(int) ($c['s']) : 0); (int) ($c['s']) : 0);
}
} }
$rowIndex += 1; $rowIndex += 1;
} }

View File

@ -0,0 +1,50 @@
<?php
namespace PhpOffice\PhpSpreadsheetTests\Functional;
use PhpOffice\PhpSpreadsheet\Reader\IReadFilter;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
class ReadBlankCellsTest extends AbstractFunctional
{
public function providerSheetFormat()
{
return [
['Xlsx'],
['Xls'],
// ['Ods'], // Broken. Requires fix in Ods reader.
// ['Csv'], // never reads blank cells
// ['Html'], // never reads blank cells
];
}
/**
* Test generate file with some empty cells
*
* @dataProvider providerSheetFormat
*
* @param array $arrayData
* @param mixed $format
*/
public function testXlsxLoadWithNoBlankCells($format)
{
$spreadsheet = new Spreadsheet();
$spreadsheet->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'));
}
}