Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
 
3
namespace PhpOffice\PhpSpreadsheet\Style;
4
 
5
class NumberFormat extends Supervisor
6
{
7
    // Pre-defined formats
8
    const FORMAT_GENERAL = 'General';
9
 
10
    const FORMAT_TEXT = '@';
11
 
12
    const FORMAT_NUMBER = '0';
13
    const FORMAT_NUMBER_0 = '0.0';
14
    const FORMAT_NUMBER_00 = '0.00';
15
    const FORMAT_NUMBER_COMMA_SEPARATED1 = '#,##0.00';
16
    const FORMAT_NUMBER_COMMA_SEPARATED2 = '#,##0.00_-';
17
 
18
    const FORMAT_PERCENTAGE = '0%';
19
    const FORMAT_PERCENTAGE_0 = '0.0%';
20
    const FORMAT_PERCENTAGE_00 = '0.00%';
21
 
22
    /** @deprecated 1.26 use FORMAT_DATE_YYYYMMDD instead */
23
    const FORMAT_DATE_YYYYMMDD2 = 'yyyy-mm-dd';
24
    const FORMAT_DATE_YYYYMMDD = 'yyyy-mm-dd';
25
    const FORMAT_DATE_DDMMYYYY = 'dd/mm/yyyy';
26
    const FORMAT_DATE_DMYSLASH = 'd/m/yy';
27
    const FORMAT_DATE_DMYMINUS = 'd-m-yy';
28
    const FORMAT_DATE_DMMINUS = 'd-m';
29
    const FORMAT_DATE_MYMINUS = 'm-yy';
30
    const FORMAT_DATE_XLSX14 = 'mm-dd-yy';
31
    const FORMAT_DATE_XLSX15 = 'd-mmm-yy';
32
    const FORMAT_DATE_XLSX16 = 'd-mmm';
33
    const FORMAT_DATE_XLSX17 = 'mmm-yy';
34
    const FORMAT_DATE_XLSX22 = 'm/d/yy h:mm';
35
    const FORMAT_DATE_DATETIME = 'd/m/yy h:mm';
36
    const FORMAT_DATE_TIME1 = 'h:mm AM/PM';
37
    const FORMAT_DATE_TIME2 = 'h:mm:ss AM/PM';
38
    const FORMAT_DATE_TIME3 = 'h:mm';
39
    const FORMAT_DATE_TIME4 = 'h:mm:ss';
40
    const FORMAT_DATE_TIME5 = 'mm:ss';
41
    const FORMAT_DATE_TIME6 = 'h:mm:ss';
42
    const FORMAT_DATE_TIME7 = 'i:s.S';
43
    const FORMAT_DATE_TIME8 = 'h:mm:ss;@';
44
    const FORMAT_DATE_YYYYMMDDSLASH = 'yyyy/mm/dd;@';
45
 
46
    const DATE_TIME_OR_DATETIME_ARRAY = [
47
        self::FORMAT_DATE_YYYYMMDD,
48
        self::FORMAT_DATE_DDMMYYYY,
49
        self::FORMAT_DATE_DMYSLASH,
50
        self::FORMAT_DATE_DMYMINUS,
51
        self::FORMAT_DATE_DMMINUS,
52
        self::FORMAT_DATE_MYMINUS,
53
        self::FORMAT_DATE_XLSX14,
54
        self::FORMAT_DATE_XLSX15,
55
        self::FORMAT_DATE_XLSX16,
56
        self::FORMAT_DATE_XLSX17,
57
        self::FORMAT_DATE_XLSX22,
58
        self::FORMAT_DATE_DATETIME,
59
        self::FORMAT_DATE_TIME1,
60
        self::FORMAT_DATE_TIME2,
61
        self::FORMAT_DATE_TIME3,
62
        self::FORMAT_DATE_TIME4,
63
        self::FORMAT_DATE_TIME5,
64
        self::FORMAT_DATE_TIME6,
65
        self::FORMAT_DATE_TIME7,
66
        self::FORMAT_DATE_TIME8,
67
        self::FORMAT_DATE_YYYYMMDDSLASH,
68
    ];
69
    const TIME_OR_DATETIME_ARRAY = [
70
        self::FORMAT_DATE_XLSX22,
71
        self::FORMAT_DATE_DATETIME,
72
        self::FORMAT_DATE_TIME1,
73
        self::FORMAT_DATE_TIME2,
74
        self::FORMAT_DATE_TIME3,
75
        self::FORMAT_DATE_TIME4,
76
        self::FORMAT_DATE_TIME5,
77
        self::FORMAT_DATE_TIME6,
78
        self::FORMAT_DATE_TIME7,
79
        self::FORMAT_DATE_TIME8,
80
    ];
81
 
82
    /** @deprecated 1.28 use FORMAT_CURRENCY_USD_INTEGER instead */
83
    const FORMAT_CURRENCY_USD_SIMPLE = '"$"#,##0_-';
84
    const FORMAT_CURRENCY_USD_INTEGER = '$#,##0_-';
85
    const FORMAT_CURRENCY_USD = '$#,##0.00_-';
86
    /** @deprecated 1.28 use FORMAT_CURRENCY_EUR_INTEGER instead */
87
    const FORMAT_CURRENCY_EUR_SIMPLE = '#,##0_-"€"';
88
    const FORMAT_CURRENCY_EUR_INTEGER = '#,##0_-[$€]';
89
    const FORMAT_CURRENCY_EUR = '#,##0.00_-[$€]';
90
    const FORMAT_ACCOUNTING_USD = '_("$"* #,##0.00_);_("$"* \(#,##0.00\);_("$"* "-"??_);_(@_)';
91
    const FORMAT_ACCOUNTING_EUR = '_("€"* #,##0.00_);_("€"* \(#,##0.00\);_("€"* "-"??_);_(@_)';
92
 
93
    /**
94
     * Excel built-in number formats.
95
     *
96
     * @var array
97
     */
98
    protected static $builtInFormats;
99
 
100
    /**
101
     * Excel built-in number formats (flipped, for faster lookups).
102
     *
103
     * @var array
104
     */
105
    protected static $flippedBuiltInFormats;
106
 
107
    /**
108
     * Format Code.
109
     *
110
     * @var null|string
111
     */
112
    protected $formatCode = self::FORMAT_GENERAL;
113
 
114
    /**
115
     * Built-in format Code.
116
     *
117
     * @var false|int
118
     */
119
    protected $builtInFormatCode = 0;
120
 
121
    /**
122
     * Create a new NumberFormat.
123
     *
124
     * @param bool $isSupervisor Flag indicating if this is a supervisor or not
125
     *                                    Leave this value at default unless you understand exactly what
126
     *                                        its ramifications are
127
     * @param bool $isConditional Flag indicating if this is a conditional style or not
128
     *                                    Leave this value at default unless you understand exactly what
129
     *                                        its ramifications are
130
     */
131
    public function __construct($isSupervisor = false, $isConditional = false)
132
    {
133
        // Supervisor?
134
        parent::__construct($isSupervisor);
135
 
136
        if ($isConditional) {
137
            $this->formatCode = null;
138
            $this->builtInFormatCode = false;
139
        }
140
    }
141
 
142
    /**
143
     * Get the shared style component for the currently active cell in currently active sheet.
144
     * Only used for style supervisor.
145
     *
146
     * @return NumberFormat
147
     */
148
    public function getSharedComponent()
149
    {
150
        /** @var Style */
151
        $parent = $this->parent;
152
 
153
        return $parent->getSharedComponent()->getNumberFormat();
154
    }
155
 
156
    /**
157
     * Build style array from subcomponents.
158
     *
159
     * @param array $array
160
     *
161
     * @return array
162
     */
163
    public function getStyleArray($array)
164
    {
165
        return ['numberFormat' => $array];
166
    }
167
 
168
    /**
169
     * Apply styles from array.
170
     *
171
     * <code>
172
     * $spreadsheet->getActiveSheet()->getStyle('B2')->getNumberFormat()->applyFromArray(
173
     *     [
174
     *         'formatCode' => NumberFormat::FORMAT_CURRENCY_EUR_SIMPLE
175
     *     ]
176
     * );
177
     * </code>
178
     *
179
     * @param array $styleArray Array containing style information
180
     *
181
     * @return $this
182
     */
183
    public function applyFromArray(array $styleArray)
184
    {
185
        if ($this->isSupervisor) {
186
            $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($this->getStyleArray($styleArray));
187
        } else {
188
            if (isset($styleArray['formatCode'])) {
189
                $this->setFormatCode($styleArray['formatCode']);
190
            }
191
        }
192
 
193
        return $this;
194
    }
195
 
196
    /**
197
     * Get Format Code.
198
     *
199
     * @return null|string
200
     */
201
    public function getFormatCode()
202
    {
203
        if ($this->isSupervisor) {
204
            return $this->getSharedComponent()->getFormatCode();
205
        }
206
        if (is_int($this->builtInFormatCode)) {
207
            return self::builtInFormatCode($this->builtInFormatCode);
208
        }
209
 
210
        return $this->formatCode;
211
    }
212
 
213
    /**
214
     * Set Format Code.
215
     *
216
     * @param string $formatCode see self::FORMAT_*
217
     *
218
     * @return $this
219
     */
220
    public function setFormatCode(string $formatCode)
221
    {
222
        if ($formatCode == '') {
223
            $formatCode = self::FORMAT_GENERAL;
224
        }
225
        if ($this->isSupervisor) {
226
            $styleArray = $this->getStyleArray(['formatCode' => $formatCode]);
227
            $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
228
        } else {
229
            $this->formatCode = $formatCode;
230
            $this->builtInFormatCode = self::builtInFormatCodeIndex($formatCode);
231
        }
232
 
233
        return $this;
234
    }
235
 
236
    /**
237
     * Get Built-In Format Code.
238
     *
239
     * @return false|int
240
     */
241
    public function getBuiltInFormatCode()
242
    {
243
        if ($this->isSupervisor) {
244
            return $this->getSharedComponent()->getBuiltInFormatCode();
245
        }
246
 
247
        // Scrutinizer says this could return true. It is wrong.
248
        return $this->builtInFormatCode;
249
    }
250
 
251
    /**
252
     * Set Built-In Format Code.
253
     *
254
     * @param int $formatCodeIndex Id of the built-in format code to use
255
     *
256
     * @return $this
257
     */
258
    public function setBuiltInFormatCode(int $formatCodeIndex)
259
    {
260
        if ($this->isSupervisor) {
261
            $styleArray = $this->getStyleArray(['formatCode' => self::builtInFormatCode($formatCodeIndex)]);
262
            $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
263
        } else {
264
            $this->builtInFormatCode = $formatCodeIndex;
265
            $this->formatCode = self::builtInFormatCode($formatCodeIndex);
266
        }
267
 
268
        return $this;
269
    }
270
 
271
    /**
272
     * Fill built-in format codes.
273
     */
274
    private static function fillBuiltInFormatCodes(): void
275
    {
276
        //  [MS-OI29500: Microsoft Office Implementation Information for ISO/IEC-29500 Standard Compliance]
277
        //  18.8.30. numFmt (Number Format)
278
        //
279
        //  The ECMA standard defines built-in format IDs
280
        //      14: "mm-dd-yy"
281
        //      22: "m/d/yy h:mm"
282
        //      37: "#,##0 ;(#,##0)"
283
        //      38: "#,##0 ;[Red](#,##0)"
284
        //      39: "#,##0.00;(#,##0.00)"
285
        //      40: "#,##0.00;[Red](#,##0.00)"
286
        //      47: "mmss.0"
287
        //      KOR fmt 55: "yyyy-mm-dd"
288
        //  Excel defines built-in format IDs
289
        //      14: "m/d/yyyy"
290
        //      22: "m/d/yyyy h:mm"
291
        //      37: "#,##0_);(#,##0)"
292
        //      38: "#,##0_);[Red](#,##0)"
293
        //      39: "#,##0.00_);(#,##0.00)"
294
        //      40: "#,##0.00_);[Red](#,##0.00)"
295
        //      47: "mm:ss.0"
296
        //      KOR fmt 55: "yyyy/mm/dd"
297
 
298
        // Built-in format codes
299
        if (empty(self::$builtInFormats)) {
300
            self::$builtInFormats = [];
301
 
302
            // General
303
            self::$builtInFormats[0] = self::FORMAT_GENERAL;
304
            self::$builtInFormats[1] = '0';
305
            self::$builtInFormats[2] = '0.00';
306
            self::$builtInFormats[3] = '#,##0';
307
            self::$builtInFormats[4] = '#,##0.00';
308
 
309
            self::$builtInFormats[9] = '0%';
310
            self::$builtInFormats[10] = '0.00%';
311
            self::$builtInFormats[11] = '0.00E+00';
312
            self::$builtInFormats[12] = '# ?/?';
313
            self::$builtInFormats[13] = '# ??/??';
314
            self::$builtInFormats[14] = 'm/d/yyyy'; // Despite ECMA 'mm-dd-yy';
315
            self::$builtInFormats[15] = 'd-mmm-yy';
316
            self::$builtInFormats[16] = 'd-mmm';
317
            self::$builtInFormats[17] = 'mmm-yy';
318
            self::$builtInFormats[18] = 'h:mm AM/PM';
319
            self::$builtInFormats[19] = 'h:mm:ss AM/PM';
320
            self::$builtInFormats[20] = 'h:mm';
321
            self::$builtInFormats[21] = 'h:mm:ss';
322
            self::$builtInFormats[22] = 'm/d/yyyy h:mm'; // Despite ECMA 'm/d/yy h:mm';
323
 
324
            self::$builtInFormats[37] = '#,##0_);(#,##0)'; //  Despite ECMA '#,##0 ;(#,##0)';
325
            self::$builtInFormats[38] = '#,##0_);[Red](#,##0)'; //  Despite ECMA '#,##0 ;[Red](#,##0)';
326
            self::$builtInFormats[39] = '#,##0.00_);(#,##0.00)'; //  Despite ECMA '#,##0.00;(#,##0.00)';
327
            self::$builtInFormats[40] = '#,##0.00_);[Red](#,##0.00)'; //  Despite ECMA '#,##0.00;[Red](#,##0.00)';
328
 
329
            self::$builtInFormats[44] = '_("$"* #,##0.00_);_("$"* \(#,##0.00\);_("$"* "-"??_);_(@_)';
330
            self::$builtInFormats[45] = 'mm:ss';
331
            self::$builtInFormats[46] = '[h]:mm:ss';
332
            self::$builtInFormats[47] = 'mm:ss.0'; //  Despite ECMA 'mmss.0';
333
            self::$builtInFormats[48] = '##0.0E+0';
334
            self::$builtInFormats[49] = '@';
335
 
336
            // CHT
337
            self::$builtInFormats[27] = '[$-404]e/m/d';
338
            self::$builtInFormats[30] = 'm/d/yy';
339
            self::$builtInFormats[36] = '[$-404]e/m/d';
340
            self::$builtInFormats[50] = '[$-404]e/m/d';
341
            self::$builtInFormats[57] = '[$-404]e/m/d';
342
 
343
            // THA
344
            self::$builtInFormats[59] = 't0';
345
            self::$builtInFormats[60] = 't0.00';
346
            self::$builtInFormats[61] = 't#,##0';
347
            self::$builtInFormats[62] = 't#,##0.00';
348
            self::$builtInFormats[67] = 't0%';
349
            self::$builtInFormats[68] = 't0.00%';
350
            self::$builtInFormats[69] = 't# ?/?';
351
            self::$builtInFormats[70] = 't# ??/??';
352
 
353
            // JPN
354
            self::$builtInFormats[28] = '[$-411]ggge"年"m"月"d"日"';
355
            self::$builtInFormats[29] = '[$-411]ggge"年"m"月"d"日"';
356
            self::$builtInFormats[31] = 'yyyy"年"m"月"d"日"';
357
            self::$builtInFormats[32] = 'h"時"mm"分"';
358
            self::$builtInFormats[33] = 'h"時"mm"分"ss"秒"';
359
            self::$builtInFormats[34] = 'yyyy"年"m"月"';
360
            self::$builtInFormats[35] = 'm"月"d"日"';
361
            self::$builtInFormats[51] = '[$-411]ggge"年"m"月"d"日"';
362
            self::$builtInFormats[52] = 'yyyy"年"m"月"';
363
            self::$builtInFormats[53] = 'm"月"d"日"';
364
            self::$builtInFormats[54] = '[$-411]ggge"年"m"月"d"日"';
365
            self::$builtInFormats[55] = 'yyyy"年"m"月"';
366
            self::$builtInFormats[56] = 'm"月"d"日"';
367
            self::$builtInFormats[58] = '[$-411]ggge"年"m"月"d"日"';
368
 
369
            // Flip array (for faster lookups)
370
            self::$flippedBuiltInFormats = array_flip(self::$builtInFormats);
371
        }
372
    }
373
 
374
    /**
375
     * Get built-in format code.
376
     *
377
     * @param int $index
378
     *
379
     * @return string
380
     */
381
    public static function builtInFormatCode($index)
382
    {
383
        // Clean parameter
384
        $index = (int) $index;
385
 
386
        // Ensure built-in format codes are available
387
        self::fillBuiltInFormatCodes();
388
 
389
        // Lookup format code
390
        if (isset(self::$builtInFormats[$index])) {
391
            return self::$builtInFormats[$index];
392
        }
393
 
394
        return '';
395
    }
396
 
397
    /**
398
     * Get built-in format code index.
399
     *
400
     * @param string $formatCodeIndex
401
     *
402
     * @return false|int
403
     */
404
    public static function builtInFormatCodeIndex($formatCodeIndex)
405
    {
406
        // Ensure built-in format codes are available
407
        self::fillBuiltInFormatCodes();
408
 
409
        // Lookup format code
410
        if (array_key_exists($formatCodeIndex, self::$flippedBuiltInFormats)) {
411
            return self::$flippedBuiltInFormats[$formatCodeIndex];
412
        }
413
 
414
        return false;
415
    }
416
 
417
    /**
418
     * Get hash code.
419
     *
420
     * @return string Hash code
421
     */
422
    public function getHashCode()
423
    {
424
        if ($this->isSupervisor) {
425
            return $this->getSharedComponent()->getHashCode();
426
        }
427
 
428
        return md5(
429
            $this->formatCode .
430
            $this->builtInFormatCode .
431
            __CLASS__
432
        );
433
    }
434
 
435
    /**
436
     * Convert a value in a pre-defined format to a PHP string.
437
     *
438
     * @param mixed $value Value to format
439
     * @param string $format Format code: see = self::FORMAT_* for predefined values;
440
     *                          or can be any valid MS Excel custom format string
441
     * @param array $callBack Callback function for additional formatting of string
442
     *
443
     * @return string Formatted string
444
     */
445
    public static function toFormattedString($value, $format, $callBack = null)
446
    {
447
        return NumberFormat\Formatter::toFormattedString($value, $format, $callBack);
448
    }
449
 
450
    protected function exportArray1(): array
451
    {
452
        $exportedArray = [];
453
        $this->exportArray2($exportedArray, 'formatCode', $this->getFormatCode());
454
 
455
        return $exportedArray;
456
    }
457
}