| 1441 |
ariadna |
1 |
<?php
|
|
|
2 |
|
|
|
3 |
namespace PhpOffice\PhpSpreadsheet\Style\NumberFormat;
|
|
|
4 |
|
|
|
5 |
use PhpOffice\PhpSpreadsheet\Style\NumberFormat;
|
|
|
6 |
|
|
|
7 |
class PercentageFormatter extends BaseFormatter
|
|
|
8 |
{
|
|
|
9 |
/** @param float|int $value */
|
|
|
10 |
public static function format($value, string $format): string
|
|
|
11 |
{
|
|
|
12 |
if ($format === NumberFormat::FORMAT_PERCENTAGE) {
|
|
|
13 |
return round((100 * $value), 0) . '%';
|
|
|
14 |
}
|
|
|
15 |
|
|
|
16 |
$value *= 100;
|
|
|
17 |
$format = self::stripQuotes($format);
|
|
|
18 |
|
|
|
19 |
[, $vDecimals] = explode('.', ((string) $value) . '.');
|
|
|
20 |
$vDecimalCount = strlen(rtrim($vDecimals, '0'));
|
|
|
21 |
|
|
|
22 |
$format = str_replace('%', '%%', $format);
|
|
|
23 |
$wholePartSize = strlen((string) floor(abs($value)));
|
|
|
24 |
$decimalPartSize = 0;
|
|
|
25 |
$placeHolders = '';
|
|
|
26 |
// Number of decimals
|
|
|
27 |
if (preg_match('/\.([?0]+)/u', $format, $matches)) {
|
|
|
28 |
$decimalPartSize = strlen($matches[1]);
|
|
|
29 |
$vMinDecimalCount = strlen(rtrim($matches[1], '?'));
|
|
|
30 |
$decimalPartSize = min(max($vMinDecimalCount, $vDecimalCount), $decimalPartSize);
|
|
|
31 |
$placeHolders = str_repeat(' ', strlen($matches[1]) - $decimalPartSize);
|
|
|
32 |
}
|
|
|
33 |
// Number of digits to display before the decimal
|
|
|
34 |
if (preg_match('/([#0,]+)\.?/u', $format, $matches)) {
|
|
|
35 |
$firstZero = preg_replace('/^[#,]*/', '', $matches[1]) ?? '';
|
|
|
36 |
$wholePartSize = max($wholePartSize, strlen($firstZero));
|
|
|
37 |
}
|
|
|
38 |
|
|
|
39 |
$wholePartSize += $decimalPartSize + (int) ($decimalPartSize > 0);
|
|
|
40 |
$replacement = "0{$wholePartSize}.{$decimalPartSize}";
|
|
|
41 |
$mask = (string) preg_replace('/[#0,]+\.?[?#0,]*/ui', "%{$replacement}F{$placeHolders}", $format);
|
|
|
42 |
|
|
|
43 |
/** @var float $valueFloat */
|
|
|
44 |
$valueFloat = $value;
|
|
|
45 |
|
|
|
46 |
return self::adjustSeparators(sprintf($mask, round($valueFloat, $decimalPartSize)));
|
|
|
47 |
}
|
|
|
48 |
}
|