mirror of
https://github.com/PHPOffice/PhpSpreadsheet.git
synced 2026-09-03 14:10:27 +00:00
ef81f19996
Fix #3899. Supersedes PR #4476, which will be changed to draft status and closed if this PR is merged. A standard cast from float to string in PHP can drop trailing decimal positions. This can lead to problems above and beyond the usual problems associated with floating point. See the superseded PR for a more complete explanation. `StringHelper::convertToString` is changed for how it handles floats. It will now do separate casts for the whole and decimal parts, and then combine the results. This affects `Cell::getValueString` and `Cell::getCalculatedValueString`. Xlsx Writer will now invoke `convertToString` before writing a float to Xml. Ods Writer already uses `getValueString`, so no change is needed there. Xls Writer writes its float values in binary, so no change is needed there. Tests are added for all 3 writers. Aside from fixing some problems, it might appear that this change introduces some new problems. For instance, setting a cell to `12345.6789` will now result in `12345.67890000000079` in the Xml. This difference is an illusion, merely a consequence of floating point rounding. If you run the following check under PhpUnit, it will pass: ```php self::assertSame(12345.6789, 12345.67890000000079); ```
32 lines
1.0 KiB
PHP
32 lines
1.0 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\TextData;
|
|
|
|
use PhpOffice\PhpSpreadsheet\Shared\StringHelper;
|
|
use PHPUnit\Framework\Attributes\DataProvider;
|
|
|
|
class ArrayToTextTest extends AllSetupTeardown
|
|
{
|
|
/** @param mixed[] $testData */
|
|
#[DataProvider('providerARRAYTOTEXT')]
|
|
public function testArrayToText(string $expectedResult, array $testData, int $mode): void
|
|
{
|
|
$worksheet = $this->getSheet();
|
|
$worksheet->fromArray($testData, null, 'A1', true);
|
|
$worksheet->getCell('H1')->setValue("=ARRAYTOTEXT(A1:C5, {$mode})");
|
|
|
|
$result = $worksheet->getCell('H1')->getCalculatedValue();
|
|
$b1SimpleCast = '12345.6789';
|
|
$b1AccurateCast = StringHelper::convertToString(12345.6789);
|
|
$expectedResult = str_replace($b1SimpleCast, $b1AccurateCast, $expectedResult);
|
|
self::assertSame($expectedResult, $result);
|
|
}
|
|
|
|
public static function providerARRAYTOTEXT(): array
|
|
{
|
|
return require 'tests/data/Calculation/TextData/ARRAYTOTEXT.php';
|
|
}
|
|
}
|