nfTlWNl rn Ѻq$³*L ZR]_-H#GDn,|2 ^C#֒Hnn!V5孱4Fϟh^|}3 稅^iI4 H Ϝf&oAY\QN#]>iZM- Qy󍃔q,7dUL_v xV8Uf*<8~w=r 3,j,m㠓Z/L_v xV8U$5 >>|weC q&柦Tn5 CӝINg5i49n/2ݝ 66\UED K\^@IL~{9 D?綁3WRw}k=-OrQtO&xT1$@[$j' ?ViqMD'ƍswPS~y~7N;7C(1Ï~@!Cnm~$D71[I~{9 +Dayrlk=-OrQt~jxDD|GN|O~'<~)?Ao3J߮d2~cVI0f% h57h5fwDɬv<~T7?9ȳ<3T;jٓBfd´, )tƔGine)[8m-Ij>T ݋7Ȥ;e/̤d"0욵Ҷf)#pI*}V,:E^d2/.E4tx#0StymrMNkb省P*UE 6#}V>CT)aMޭ $-:GN.x&(EG5YN*'T3[kExi]~θreҕ:6a>Ìؒ;Ug~ِ&pW8[˗@ҵU0,'(F^&bC2fCnim68[˗@ҵUl9сEU^JD!T{Mdo~#_Jm("LW|61SZb+_:onl D`~Ǯ*: Ԓǣ6Cט $͹qD+n o+Wob,t!w==aw*,5*+ȶ;cq)zAnz\wΨ.?؁.пiH#  SLZBgNM+-SՁ6+˽E8 Hӻ7Gya4&Yќ4J\&9JU^&\nAP避7HMMP=mnS)8IIM`##EH6 Cmn՞< K] beẼb8V Ŕ y!amLQxckekMV$WPcfPzf'$:?ļ9eqs= -`nrgҬJZP6dFʅs){- F*fRx%J5&TB5FٓFlޥ5iẸt hydİxD( iJ(7ɠzlgD99K4ƪz9u#jk"#Ge@ߕѩu ݴ/32E>IPk>0Ulph(| _f"M٬6cWAl^ ڈYjFDj1pjH3K & N|SG%7}2+l\zk&%G g /ԗEim#${T@C'm} Z/Zȅ{T ^URar:%nM4'h~{w(uK_b7{d%=>rJ>P˺ۖկ#BxQK2% W/b95VN( p"ҹWo4C $4'h~{w(uZS$ N/aY*ue8;1۹UC"X`zpyzZ(mx\}W?lqʵNO - 0)) { $color = $colors[1]; $format = $sections[1]; } else { $color = $colors[2]; $format = $sections[2]; } } break; } return [$color, $format, $absval]; } /** * Convert a value in a pre-defined format to a PHP string. * * @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 array $callBack Callback function for additional formatting of string * * @return string Formatted string */ public static function toFormattedString($value, $format, $callBack = null) { if (is_bool($value)) { return $value ? Calculation::getTRUE() : Calculation::getFALSE(); } // For now we do not treat strings in sections, although section 4 of a format code affects strings // Process a single block format code containing @ for text substitution if (preg_match(self::SECTION_SPLIT, $format) === 0 && preg_match(self::SYMBOL_AT, $format) === 1) { return str_replace('"', '', preg_replace(self::SYMBOL_AT, (string) $value, $format) ?? ''); } // If we have a text value, return it "as is" if (!is_numeric($value)) { return (string) $value; } // For 'General' format code, we just pass the value although this is not entirely the way Excel does it, // it seems to round numbers to a total of 10 digits. if (($format === NumberFormat::FORMAT_GENERAL) || ($format === NumberFormat::FORMAT_TEXT)) { return (string) $value; } // Ignore square-$-brackets prefix in format string, like "[$-411]ge.m.d", "[$-010419]0%", etc $format = (string) preg_replace('/^\[\$-[^\]]*\]/', '', $format); $format = (string) preg_replace_callback( '/(["])(?:(?=(\\\\?))\\2.)*?\\1/u', function ($matches) { return str_replace('.', chr(0x00), $matches[0]); }, $format ); // Convert any other escaped characters to quoted strings, e.g. (\T to "T") $format = (string) preg_replace('/(\\\(((.)(?!((AM\/PM)|(A\/P))))|([^ ])))(?=(?:[^"]|"[^"]*")*$)/ui', '"${2}"', $format); // Get the sections, there can be up to four sections, separated with a semi-colon (but only if not a quoted literal) $sections = preg_split(self::SECTION_SPLIT, $format) ?: []; [$colors, $format, $value] = self::splitFormatForSectionSelection($sections, $value); // 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 $format = (string) preg_replace('/_.?/ui', ' ', $format); // Let's begin inspecting the format and converting the value to a formatted string if ( // Check for date/time characters (not inside quotes) (preg_match('/(\[\$[A-Z]*-[0-9A-F]*\])*[hmsdy](?=(?:[^"]|"[^"]*")*$)/miu', $format)) // A date/time with a decimal time shouldn't have a digit placeholder before the decimal point && (preg_match('/[0\?#]\.(?![^\[]*\])/miu', $format) === 0) ) { // datetime format $value = DateFormatter::format($value, $format); } else { if (substr($format, 0, 1) === '"' && substr($format, -1, 1) === '"' && substr_count($format, '"') === 2) { $value = substr($format, 1, -1); } elseif (preg_match('/[0#, ]%/', $format)) { // % number format - avoid weird '-0' problem $value = PercentageFormatter::format(0 + (float) $value, $format); } else { $value = NumberFormatter::format($value, $format); } } // Additional formatting provided by callback function if ($callBack !== null) { [$writerInstance, $function] = $callBack; $value = $writerInstance->$function($value, $colors); } return str_replace(chr(0x00), '.', $value); } }