From 8c0663486b77d4b8137d72dc2207a16f659760e3 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Mon, 31 Jan 2011 17:18:10 +0000 Subject: [PATCH] Feature: Improved toFormattedString() handling for Currency and Accounting format masks to render currency symbols git-svn-id: https://phpexcel.svn.codeplex.com/svn/trunk@67614 2327b42d-5241-43d6-9e2a-de5ac946f064 --- Classes/PHPExcel/Shared/String.php | 42 +++++++++++++++++++++++-- Classes/PHPExcel/Style/NumberFormat.php | 30 ++++++++++++------ changelog.txt | 1 + 3 files changed, 61 insertions(+), 12 deletions(-) diff --git a/Classes/PHPExcel/Shared/String.php b/Classes/PHPExcel/Shared/String.php index c9ec811e..20cdd710 100644 --- a/Classes/PHPExcel/Shared/String.php +++ b/Classes/PHPExcel/Shared/String.php @@ -69,6 +69,13 @@ class PHPExcel_Shared_String */ private static $_thousandsSeparator; + /** + * Currency code + * + * @var string + */ + private static $_currencyCode; + /** * Is mbstring extension avalable? * @@ -598,8 +605,7 @@ class PHPExcel_Shared_String self::$_decimalSeparator = $localeconv['decimal_point'] != '' ? $localeconv['decimal_point'] : $localeconv['mon_decimal_point']; - if (self::$_decimalSeparator == '') - { + if (self::$_decimalSeparator == '') { // Default to . self::$_decimalSeparator = '.'; } @@ -645,6 +651,38 @@ class PHPExcel_Shared_String self::$_thousandsSeparator = $pValue; } + /** + * Get the currency code. If it has not yet been set explicitly, try to obtain the + * symbol information from locale. + * + * @return string + */ + public static function getCurrencyCode() + { + if (!isset(self::$_currencyCode)) { + $localeconv = localeconv(); + self::$_currencyCode = $localeconv['currency_symbol'] != '' + ? $localeconv['currency_symbol'] : $localeconv['int_curr_symbol']; + + if (self::$_currencyCode == '') { + // Default to $ + self::$_currencyCode = '$'; + } + } + return self::$_currencyCode; + } + + /** + * Set the currency code. Only used by PHPExcel_Style_NumberFormat::toFormattedString() + * to format output by PHPExcel_Writer_HTML and PHPExcel_Writer_PDF + * + * @param string $pValue Character for currency code + */ + public static function setCurrencyCode($pValue = '$') + { + self::$_currencyCode = $pValue; + } + /** * Convert SYLK encoded string to UTF-8 * diff --git a/Classes/PHPExcel/Style/NumberFormat.php b/Classes/PHPExcel/Style/NumberFormat.php index 744020bd..5d6e03a4 100644 --- a/Classes/PHPExcel/Style/NumberFormat.php +++ b/Classes/PHPExcel/Style/NumberFormat.php @@ -605,8 +605,8 @@ class PHPExcel_Style_NumberFormat implements PHPExcel_IComparable // Some non-number characters are escaped with \, which we don't need $format = preg_replace("/\\\\/", '', $format); - // Some non-number strings are quoted, so we'll get rid of the quotes - $format = preg_replace('/"/', '', $format); + // Some non-number strings are quoted, so we'll get rid of the quotes, likewise any positional * symbols + $format = str_replace(array('"','*'), '', $format); // Find out if we need thousands separator // This is indicated by a comma enclosed by a digit placeholder: @@ -663,9 +663,10 @@ class PHPExcel_Style_NumberFormat implements PHPExcel_IComparable // Strip # $format = preg_replace('/\\#/', '', $format); + $n = "/\[[^\]]+\]/"; + $m = preg_replace($n, '', $format); $number_regex = "/(0+)(\.?)(0*)/"; - $matches = array(); - if (preg_match($number_regex, $format, $matches)) { + if (preg_match($number_regex, $m, $matches)) { $left = $matches[1]; $dec = $matches[2]; $right = $matches[3]; @@ -675,12 +676,11 @@ class PHPExcel_Style_NumberFormat implements PHPExcel_IComparable if ($useThousands) { $value = number_format( - $value - , strlen($right) - , PHPExcel_Shared_String::getDecimalSeparator() - , PHPExcel_Shared_String::getThousandsSeparator() - ); - + $value + , strlen($right) + , PHPExcel_Shared_String::getDecimalSeparator() + , PHPExcel_Shared_String::getThousandsSeparator() + ); } else { $sprintf_pattern = "%0$minWidth." . strlen($right) . "f"; $value = sprintf($sprintf_pattern, $value); @@ -689,6 +689,16 @@ class PHPExcel_Style_NumberFormat implements PHPExcel_IComparable $value = preg_replace($number_regex, $value, $format); } } + if (preg_match('/\[\$(.*)\]/u', $format, $m)) { + // Currency or Accounting + $currencyFormat = $m[0]; + $currencyCode = $m[1]; + list($currencyCode) = explode('-',$currencyCode); + if ($currencyCode == '') { + $currencyCode = PHPExcel_Shared_String::getCurrencyCode(); + } + $value = preg_replace('/\[\$([^\]]*)\]/u',$currencyCode,$value); + } } } diff --git a/changelog.txt b/changelog.txt index 3b28d570..4a4015ec 100644 --- a/changelog.txt +++ b/changelog.txt @@ -34,6 +34,7 @@ Fixed in SVN: Functionally, these are identical to the toArray() method, except that they take an additional first parameter of a Range (e.g. 'B2:C3') or a Named Range name. Modified the toArray() method so that it actually uses rangeToArray(). - Feature: (MBaker) Added support for cell comments in the OOCalc, Gnumeric and Excel2003XML Readers, and in the Excel5 Reader +- Feature: (MBaker) Improved toFormattedString() handling for Currency and Accounting formats to render currency symbols - Bugfix: (MBaker) Work item 14888 - Simple =IF() formula disappears - Bugfix: (MBaker) Work item 14898 - PHP Warning: preg_match(): Compilation failed: PCRE does not support \\L, \\l, \\N, \\P, \\p, \\U, \\u, or \\X - Bugfix: (MBaker) Work item 14901 - VLOOKUP choking on parameters in PHPExcel.1.7.5/PHPExcel_Writer_Excel2007