diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ef24bfb3e..be6db25669 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org). ### Added - Support for configuring a Chart Title's overlay [PR #3325](https://github.com/PHPOffice/PhpSpreadsheet/pull/3325) +- Wizards for defining Number Format masks for Numbers, Percentages, Scientific, Currency and Accounting [PR #3334](https://github.com/PHPOffice/PhpSpreadsheet/pull/3334) ### Changed diff --git a/src/PhpSpreadsheet/Style/NumberFormat/Wizard/Accounting.php b/src/PhpSpreadsheet/Style/NumberFormat/Wizard/Accounting.php new file mode 100644 index 0000000000..803a0e5ac7 --- /dev/null +++ b/src/PhpSpreadsheet/Style/NumberFormat/Wizard/Accounting.php @@ -0,0 +1,79 @@ +setCurrencyCode($currencyCode); + $this->setThousandsSeparator($thousandsSeparator); + $this->setDecimals($decimals); + $this->setCurrencySymbolPosition($currencySymbolPosition); + $this->setCurrencySymbolSpacing($currencySymbolSpacing); + $this->setLocale($locale); + } + + protected function getLocaleFormat(): string + { + $formatter = new Locale($this->fullLocale, NumberFormatter::CURRENCY_ACCOUNTING); // @phpstan-ignore-line + + return str_replace('¤', $this->formatCurrencyCode(), $formatter->format()); + } + + private function formatCurrencyCode(): string + { + if ($this->locale === null) { + return $this->currencyCode . '*'; + } + + return "[\${$this->currencyCode}-{$this->locale}]"; + } + + public function format(): string + { + if ($this->localeFormat !== null) { + return $this->localeFormat; + } + + return sprintf( + '_-%s%s%s0%s%s%s_-', + $this->currencySymbolPosition === self::LEADING_SYMBOL ? $this->formatCurrencyCode() : null, + ( + $this->currencySymbolPosition === self::LEADING_SYMBOL && + $this->currencySymbolSpacing === self::SYMBOL_WITH_SPACING + ) ? ' ' : '', + $this->thousandsSeparator ? '#,##' : null, + $this->decimals > 0 ? '.' . str_repeat('0', $this->decimals) : null, + ( + $this->currencySymbolPosition === self::TRAILING_SYMBOL && + $this->currencySymbolSpacing === self::SYMBOL_WITH_SPACING + ) ? ' ' : '', + $this->currencySymbolPosition === self::TRAILING_SYMBOL ? $this->formatCurrencyCode() : null + ); + } +} diff --git a/src/PhpSpreadsheet/Style/NumberFormat/Wizard/Currency.php b/src/PhpSpreadsheet/Style/NumberFormat/Wizard/Currency.php new file mode 100644 index 0000000000..b25bbfd871 --- /dev/null +++ b/src/PhpSpreadsheet/Style/NumberFormat/Wizard/Currency.php @@ -0,0 +1,108 @@ +setCurrencyCode($currencyCode); + $this->setThousandsSeparator($thousandsSeparator); + $this->setDecimals($decimals); + $this->setCurrencySymbolPosition($currencySymbolPosition); + $this->setCurrencySymbolSpacing($currencySymbolSpacing); + $this->setLocale($locale); + } + + public function setCurrencyCode(string $currencyCode): void + { + $this->currencyCode = $currencyCode; + } + + public function setCurrencySymbolPosition(bool $currencySymbolPosition = self::LEADING_SYMBOL): void + { + $this->currencySymbolPosition = $currencySymbolPosition; + } + + public function setCurrencySymbolSpacing(bool $currencySymbolSpacing = self::SYMBOL_WITHOUT_SPACING): void + { + $this->currencySymbolSpacing = $currencySymbolSpacing; + } + + protected function getLocaleFormat(): string + { + $formatter = new Locale($this->fullLocale, NumberFormatter::CURRENCY); // @phpstan-ignore-line + + return str_replace('¤', $this->formatCurrencyCode(), $formatter->format()); + } + + private function formatCurrencyCode(): string + { + if ($this->locale === null) { + return $this->currencyCode; + } + + return "[\${$this->currencyCode}-{$this->locale}]"; + } + + public function format(): string + { + if ($this->localeFormat !== null) { + return $this->localeFormat; + } + + return sprintf( + '%s%s%s0%s%s%s', + $this->currencySymbolPosition === self::LEADING_SYMBOL ? $this->formatCurrencyCode() : null, + ( + $this->currencySymbolPosition === self::LEADING_SYMBOL && + $this->currencySymbolSpacing === self::SYMBOL_WITH_SPACING + ) ? "\u{a0}" : '', + $this->thousandsSeparator ? '#,##' : null, + $this->decimals > 0 ? '.' . str_repeat('0', $this->decimals) : null, + ( + $this->currencySymbolPosition === self::TRAILING_SYMBOL && + $this->currencySymbolSpacing === self::SYMBOL_WITH_SPACING + ) ? "\u{a0}" : '', + $this->currencySymbolPosition === self::TRAILING_SYMBOL ? $this->formatCurrencyCode() : null + ); + } +} diff --git a/src/PhpSpreadsheet/Style/NumberFormat/Wizard/Locale.php b/src/PhpSpreadsheet/Style/NumberFormat/Wizard/Locale.php new file mode 100644 index 0000000000..2253e8120e --- /dev/null +++ b/src/PhpSpreadsheet/Style/NumberFormat/Wizard/Locale.php @@ -0,0 +1,37 @@ +[a-z]{2})([-_](?P