Merge commit from fork

This commit is contained in:
oleibman
2026-04-18 23:10:20 -07:00
committed by GitHub
parent 9b90dee03d
commit f1eb4e6980
3 changed files with 31 additions and 14 deletions
+2 -2
View File
@@ -479,12 +479,12 @@ class NumberFormat extends Supervisor
* @param null|bool|float|int|RichText|string $value Value to format
* @param string $format Format code: see = self::FORMAT_* for predefined values;
* or can be any valid MS Excel custom format string
* @param ?mixed[] $callBack Callback function for additional formatting of string
* @param null|callable(string, string): string $callBack Callback function for additional formatting of string
* @param bool $lessFloatPrecision If true, unstyled floats will be converted to a more human-friendly but less computationally accurate value
*
* @return string Formatted string
*/
public static function toFormattedString(mixed $value, string $format, ?array $callBack = null, bool $lessFloatPrecision = false): string
public static function toFormattedString(mixed $value, string $format, ?callable $callBack = null, bool $lessFloatPrecision = false): string
{
return NumberFormat\Formatter::toFormattedString($value, $format, $callBack, $lessFloatPrecision);
}
@@ -48,7 +48,7 @@ class Formatter extends BaseFormatter
* @param float|int|numeric-string $value value to be formatted
* @param string[] $sections
*
* @return mixed[]
* @return array{string, string, float|int|numeric-string}
*/
private static function splitFormatForSectionSelection(array $sections, mixed $value): array
{
@@ -118,12 +118,12 @@ class Formatter extends BaseFormatter
* @param null|array<mixed>|bool|float|int|RichText|string $value Value to format
* @param string $format Format code: see = self::FORMAT_* for predefined values;
* or can be any valid MS Excel custom format string
* @param null|array<mixed>|callable $callBack Callback function for additional formatting of string
* @param null|callable(string, string): string $callBack Callback function for additional formatting of string
* @param bool $lessFloatPrecision If true, unstyled floats will be converted to a more human-friendly but less computationally accurate value
*
* @return string Formatted string
*/
public static function toFormattedString($value, string $format, null|array|callable $callBack = null, bool $lessFloatPrecision = false): string
public static function toFormattedString($value, string $format, ?callable $callBack = null, bool $lessFloatPrecision = false): string
{
while (is_array($value)) {
$value = array_shift($value);
@@ -136,7 +136,12 @@ class Formatter extends BaseFormatter
$formatx = str_replace('\"', self::QUOTE_REPLACEMENT, $format);
if (preg_match(self::SECTION_SPLIT, $format) === 0 && preg_match(self::SYMBOL_AT, $formatx) === 1) {
if (!str_contains($format, '"')) {
return str_replace('@', StringHelper::convertToString($value, lessFloatPrecision: $lessFloatPrecision), $format);
$temp = str_replace('@', StringHelper::convertToString($value, lessFloatPrecision: $lessFloatPrecision), $format);
if (is_callable($callBack)) {
$temp = $callBack($temp, $format);
}
return $temp;
}
//escape any dollar signs on the string, so they are not replaced with an empty value
$value = str_replace(
@@ -148,7 +153,6 @@ class Formatter extends BaseFormatter
if (is_callable($callBack)) {
$temp = $callBack($temp, $formatx);
}
/** @var string $temp */
return str_replace(
['"', self::QUOTE_REPLACEMENT],
@@ -193,7 +197,6 @@ class Formatter extends BaseFormatter
// In Excel formats, "_" is used to add spacing,
// The following character indicates the size of the spacing, which we can't do in HTML, so we just use a standard space
/** @var string */
$temp = $format;
$format = (string) preg_replace('/_.?/ui', ' ', $temp);
@@ -215,11 +218,9 @@ class Formatter extends BaseFormatter
$value = substr($format, 1, -1);
} elseif (preg_match('/[0#, ]%/', $format)) {
// % number format - avoid weird '-0' problem
/** @var float */
$temp = $value;
$value = PercentageFormatter::format(0 + (float) $temp, $format);
} else {
/** @var float|int|numeric-string */
$temp = $value;
$value = NumberFormatter::format($temp, $format);
}
@@ -229,7 +230,6 @@ class Formatter extends BaseFormatter
if (is_callable($callBack)) {
$value = $callBack($value, $colors);
}
/** @var string $value */
return str_replace(chr(0x00), '.', $value);
}
@@ -6,16 +6,17 @@ namespace PhpOffice\PhpSpreadsheetTests\Writer\Html;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Html as HtmlWriter;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
class AtSignFormatTest extends TestCase
{
public function testAtSignFormat(): void
#[DataProvider('providerFormat')]
public function testAtSignFormat(string $formatCode): void
{
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
$payload = '<img src=x onerror=alert(document.domain)>';
$formatCode = '@ "items"';
$sheet->setCellValue('A1', $payload);
$sheet->getStyle('A1')
->getNumberFormat()
@@ -23,7 +24,23 @@ class AtSignFormatTest extends TestCase
$writer = new HtmlWriter($spreadsheet);
$html = $writer->generateHTMLAll();
self::assertStringContainsString('<td class="column0 style1 s">&lt;img src=x onerror=alert(document.domain)&gt; items</td>', $html);
self::assertStringContainsString('&lt;img src=x onerror=alert(document.domain)&gt', $html);
self::assertStringNotContainsString('<img src=x onerror=alert(document.domain)>', $html);
$spreadsheet->disconnectWorksheets();
}
/** @return array<array{string}> */
public static function providerFormat(): array
{
return [
['General'],
['#'],
['yyyy-mm-dd'],
['0%'],
['@'],
['@ "items"'],
['. @'],
['@ '],
];
}
}