mirror of
https://github.com/PHPOffice/PhpSpreadsheet.git
synced 2026-08-30 03:59:11 +00:00
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:
@@ -767,7 +767,12 @@ class Xlsx extends BaseReader
|
||||
break;
|
||||
case 'b':
|
||||
if (!isset($c->f)) {
|
||||
$value = self::castToBoolean($c);
|
||||
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);
|
||||
}
|
||||
$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.
Reference in New Issue
Block a user