Modify XLSX RW to keep decimal for floats with a zero decimal part
Prior to 1.10, all numeric values where read as floats. In 1.10 numeric values are read using 0 + x, which relies on PHP type juggling rules. As a result, float(0.0) is written as string('0'), then read back as int(0). This fix causes the writer to retain the the decimal for float values such that a reader can differentiate floats from ints. Closes #1262
This commit is contained in:
parent
9552172b85
commit
cf30c2a824
|
@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org).
|
||||||
|
|
||||||
- FLOOR() function accept negative number and negative significance [#1245](https://github.com/PHPOffice/PhpSpreadsheet/pull/1245)
|
- FLOOR() function accept negative number and negative significance [#1245](https://github.com/PHPOffice/PhpSpreadsheet/pull/1245)
|
||||||
- Correct column style even when using rowspan [#1249](https://github.com/PHPOffice/PhpSpreadsheet/pull/1249)
|
- Correct column style even when using rowspan [#1249](https://github.com/PHPOffice/PhpSpreadsheet/pull/1249)
|
||||||
|
- XLSX reader/writer keep decimal for floats with a zero decimal part [#1262](https://github.com/PHPOffice/PhpSpreadsheet/pull/1262)
|
||||||
|
|
||||||
## [1.10.0] - 2019-11-18
|
## [1.10.0] - 2019-11-18
|
||||||
|
|
||||||
|
|
|
@ -729,15 +729,6 @@ class Xlsx extends BaseReader
|
||||||
|
|
||||||
// read empty cells or the cells are not empty
|
// read empty cells or the cells are not empty
|
||||||
if ($this->readEmptyCells || ($value !== null && $value !== '')) {
|
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Rich text?
|
// Rich text?
|
||||||
if ($value instanceof RichText && $this->readDataOnly) {
|
if ($value instanceof RichText && $this->readDataOnly) {
|
||||||
$value = $value->getPlainText();
|
$value = $value->getPlainText();
|
||||||
|
|
|
@ -1135,6 +1135,13 @@ class Worksheet extends WriterPart
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case 'n': // Numeric
|
case 'n': // Numeric
|
||||||
|
//force a decimal to be written if the type is float
|
||||||
|
if (is_float($cellValue)) {
|
||||||
|
$cellValue = (string) $cellValue;
|
||||||
|
if (strpos($cellValue, '.') === false) {
|
||||||
|
$cellValue = $cellValue . '.0';
|
||||||
|
}
|
||||||
|
}
|
||||||
// force point as decimal separator in case current locale uses comma
|
// force point as decimal separator in case current locale uses comma
|
||||||
$objWriter->writeElement('v', str_replace(',', '.', $cellValue));
|
$objWriter->writeElement('v', str_replace(',', '.', $cellValue));
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace PhpOffice\PhpSpreadsheetTests\Writer\Xlsx;
|
||||||
|
|
||||||
|
use PhpOffice\PhpSpreadsheet\Reader\Xlsx as Reader;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Settings;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Shared\File;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Writer\Xlsx as Writer;
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
|
class FloatsRetainedTest extends TestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @dataProvider providerIntyFloatsRetainedByWriter
|
||||||
|
*
|
||||||
|
* @param float|int $value
|
||||||
|
*/
|
||||||
|
public function testIntyFloatsRetainedByWriter($value)
|
||||||
|
{
|
||||||
|
$outputFilename = tempnam(File::sysGetTempDir(), 'phpspreadsheet-test');
|
||||||
|
Settings::setLibXmlLoaderOptions(null);
|
||||||
|
$sheet = new Spreadsheet();
|
||||||
|
$sheet->getActiveSheet()->getCell('A1')->setValue($value);
|
||||||
|
|
||||||
|
$writer = new Writer($sheet);
|
||||||
|
$writer->save($outputFilename);
|
||||||
|
|
||||||
|
$reader = new Reader();
|
||||||
|
$sheet = $reader->load($outputFilename);
|
||||||
|
|
||||||
|
$this->assertSame($value, $sheet->getActiveSheet()->getCell('A1')->getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function providerIntyFloatsRetainedByWriter()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
[-1.0],
|
||||||
|
[-1],
|
||||||
|
[0.0],
|
||||||
|
[0],
|
||||||
|
[1.0],
|
||||||
|
[1],
|
||||||
|
[1e-3],
|
||||||
|
[1.3e-10],
|
||||||
|
[1e10],
|
||||||
|
[3.00000000000000000001],
|
||||||
|
[99999999999999999],
|
||||||
|
[99999999999999999.0],
|
||||||
|
[999999999999999999999999999999999999999999],
|
||||||
|
[999999999999999999999999999999999999999999.0],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue