Xlsx Reader Cell DataType Numeric or Boolean Without Value (#2489)
Fix #2488. When Excel sees this situation, it leaves the value of the cell as null rather than casting to the specified DataType. It doesn't really make sense to change setValueExplicit to adopt this convention; it should be sufficient to recognize the situation in the Reader and act there. The same sort of situation might apply to strings, but I don't see any practical difference between null string and null even if so.
This commit is contained in:
parent
95d9cc965d
commit
06ea9ead2b
|
|
@ -767,7 +767,12 @@ class Xlsx extends BaseReader
|
|||
break;
|
||||
case 'b':
|
||||
if (!isset($c->f)) {
|
||||
if (isset($c->v)) {
|
||||
$value = self::castToBoolean($c);
|
||||
} else {
|
||||
$value = null;
|
||||
$cellDataType = DATATYPE::TYPE_NULL;
|
||||
}
|
||||
} else {
|
||||
// Formula
|
||||
$this->castToFormula($c, $r, $cellDataType, $value, $calculatedValue, $sharedFormulas, 'castToBoolean');
|
||||
|
|
@ -821,10 +826,12 @@ class Xlsx extends BaseReader
|
|||
// Assign value
|
||||
if ($cellDataType != '') {
|
||||
// it is possible, that datatype is numeric but with an empty string, which result in an error
|
||||
if ($cellDataType === DataType::TYPE_NUMERIC && $value === '') {
|
||||
$cellDataType = DataType::TYPE_STRING;
|
||||
if ($cellDataType === DataType::TYPE_NUMERIC && ($value === '' || $value === null)) {
|
||||
$cellDataType = DataType::TYPE_NULL;
|
||||
}
|
||||
if ($cellDataType !== DataType::TYPE_NULL) {
|
||||
$cell->setValueExplicit($value, $cellDataType);
|
||||
}
|
||||
} else {
|
||||
$cell->setValue($value);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,50 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Reader\Xlsx;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\IOFactory;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class Issue2488Test extends TestCase
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private static $testbook = 'tests/data/Reader/XLSX/issue.2488.xlsx';
|
||||
|
||||
public function testPreliminaries(): void
|
||||
{
|
||||
$file = 'zip://';
|
||||
$file .= self::$testbook;
|
||||
$file .= '#xl/worksheets/sheet1.xml';
|
||||
$data = file_get_contents($file);
|
||||
// confirm that file contains expected namespaced xml tag
|
||||
if ($data === false) {
|
||||
self::fail('Unable to read file');
|
||||
} else {
|
||||
self::assertStringContainsString('<c r="E1" t="n" />', $data);
|
||||
self::assertStringContainsString('<c r="E2" t="s" />', $data);
|
||||
self::assertStringContainsString('<c r="D3" t="b" />', $data);
|
||||
}
|
||||
}
|
||||
|
||||
public function testIssue2450(): void
|
||||
{
|
||||
// Cell explicitly typed as numeric but without value.
|
||||
$filename = self::$testbook;
|
||||
$reader = IOFactory::createReader('Xlsx');
|
||||
$spreadsheet = $reader->load($filename);
|
||||
$sheet = $spreadsheet->getActiveSheet();
|
||||
// E1 and D3 are numeric/boolean without value.
|
||||
// So is E2, but I don't see a practical difference
|
||||
// between null string and null in that case.
|
||||
$expected = [
|
||||
[1, 2, 3, 0, null, -1, -2, -3],
|
||||
['a', 'b', 'c', 'xxx', '', 'd', 'e', 'f'],
|
||||
[false, false, false, null, true, true, true, true],
|
||||
];
|
||||
self::assertSame($expected, $sheet->toArray());
|
||||
|
||||
$spreadsheet->disconnectWorksheets();
|
||||
}
|
||||
}
|
||||
Binary file not shown.
Loading…
Reference in New Issue