Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1441 ariadna 1
<?php
2
 
3
namespace PhpOffice\PhpSpreadsheet\Worksheet;
4
 
5
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
6
use PhpOffice\PhpSpreadsheet\Exception as PhpSpreadsheetException;
7
 
8
/**
9
 * <code>
10
 * Paper size taken from Office Open XML Part 4 - Markup Language Reference, page 1988:.
11
 *
12
 * 1 = Letter paper (8.5 in. by 11 in.)
13
 * 2 = Letter small paper (8.5 in. by 11 in.)
14
 * 3 = Tabloid paper (11 in. by 17 in.)
15
 * 4 = Ledger paper (17 in. by 11 in.)
16
 * 5 = Legal paper (8.5 in. by 14 in.)
17
 * 6 = Statement paper (5.5 in. by 8.5 in.)
18
 * 7 = Executive paper (7.25 in. by 10.5 in.)
19
 * 8 = A3 paper (297 mm by 420 mm)
20
 * 9 = A4 paper (210 mm by 297 mm)
21
 * 10 = A4 small paper (210 mm by 297 mm)
22
 * 11 = A5 paper (148 mm by 210 mm)
23
 * 12 = B4 paper (250 mm by 353 mm)
24
 * 13 = B5 paper (176 mm by 250 mm)
25
 * 14 = Folio paper (8.5 in. by 13 in.)
26
 * 15 = Quarto paper (215 mm by 275 mm)
27
 * 16 = Standard paper (10 in. by 14 in.)
28
 * 17 = Standard paper (11 in. by 17 in.)
29
 * 18 = Note paper (8.5 in. by 11 in.)
30
 * 19 = #9 envelope (3.875 in. by 8.875 in.)
31
 * 20 = #10 envelope (4.125 in. by 9.5 in.)
32
 * 21 = #11 envelope (4.5 in. by 10.375 in.)
33
 * 22 = #12 envelope (4.75 in. by 11 in.)
34
 * 23 = #14 envelope (5 in. by 11.5 in.)
35
 * 24 = C paper (17 in. by 22 in.)
36
 * 25 = D paper (22 in. by 34 in.)
37
 * 26 = E paper (34 in. by 44 in.)
38
 * 27 = DL envelope (110 mm by 220 mm)
39
 * 28 = C5 envelope (162 mm by 229 mm)
40
 * 29 = C3 envelope (324 mm by 458 mm)
41
 * 30 = C4 envelope (229 mm by 324 mm)
42
 * 31 = C6 envelope (114 mm by 162 mm)
43
 * 32 = C65 envelope (114 mm by 229 mm)
44
 * 33 = B4 envelope (250 mm by 353 mm)
45
 * 34 = B5 envelope (176 mm by 250 mm)
46
 * 35 = B6 envelope (176 mm by 125 mm)
47
 * 36 = Italy envelope (110 mm by 230 mm)
48
 * 37 = Monarch envelope (3.875 in. by 7.5 in.).
49
 * 38 = 6 3/4 envelope (3.625 in. by 6.5 in.)
50
 * 39 = US standard fanfold (14.875 in. by 11 in.)
51
 * 40 = German standard fanfold (8.5 in. by 12 in.)
52
 * 41 = German legal fanfold (8.5 in. by 13 in.)
53
 * 42 = ISO B4 (250 mm by 353 mm)
54
 * 43 = Japanese double postcard (200 mm by 148 mm)
55
 * 44 = Standard paper (9 in. by 11 in.)
56
 * 45 = Standard paper (10 in. by 11 in.)
57
 * 46 = Standard paper (15 in. by 11 in.)
58
 * 47 = Invite envelope (220 mm by 220 mm)
59
 * 50 = Letter extra paper (9.275 in. by 12 in.)
60
 * 51 = Legal extra paper (9.275 in. by 15 in.)
61
 * 52 = Tabloid extra paper (11.69 in. by 18 in.)
62
 * 53 = A4 extra paper (236 mm by 322 mm)
63
 * 54 = Letter transverse paper (8.275 in. by 11 in.)
64
 * 55 = A4 transverse paper (210 mm by 297 mm)
65
 * 56 = Letter extra transverse paper (9.275 in. by 12 in.)
66
 * 57 = SuperA/SuperA/A4 paper (227 mm by 356 mm)
67
 * 58 = SuperB/SuperB/A3 paper (305 mm by 487 mm)
68
 * 59 = Letter plus paper (8.5 in. by 12.69 in.)
69
 * 60 = A4 plus paper (210 mm by 330 mm)
70
 * 61 = A5 transverse paper (148 mm by 210 mm)
71
 * 62 = JIS B5 transverse paper (182 mm by 257 mm)
72
 * 63 = A3 extra paper (322 mm by 445 mm)
73
 * 64 = A5 extra paper (174 mm by 235 mm)
74
 * 65 = ISO B5 extra paper (201 mm by 276 mm)
75
 * 66 = A2 paper (420 mm by 594 mm)
76
 * 67 = A3 transverse paper (297 mm by 420 mm)
77
 * 68 = A3 extra transverse paper (322 mm by 445 mm)
78
 * </code>
79
 */
80
class PageSetup
81
{
82
    // Paper size
83
    const PAPERSIZE_LETTER = 1;
84
    const PAPERSIZE_LETTER_SMALL = 2;
85
    const PAPERSIZE_TABLOID = 3;
86
    const PAPERSIZE_LEDGER = 4;
87
    const PAPERSIZE_LEGAL = 5;
88
    const PAPERSIZE_STATEMENT = 6;
89
    const PAPERSIZE_EXECUTIVE = 7;
90
    const PAPERSIZE_A3 = 8;
91
    const PAPERSIZE_A4 = 9;
92
    const PAPERSIZE_A4_SMALL = 10;
93
    const PAPERSIZE_A5 = 11;
94
    const PAPERSIZE_B4 = 12;
95
    const PAPERSIZE_B5 = 13;
96
    const PAPERSIZE_FOLIO = 14;
97
    const PAPERSIZE_QUARTO = 15;
98
    const PAPERSIZE_STANDARD_1 = 16;
99
    const PAPERSIZE_STANDARD_2 = 17;
100
    const PAPERSIZE_NOTE = 18;
101
    const PAPERSIZE_NO9_ENVELOPE = 19;
102
    const PAPERSIZE_NO10_ENVELOPE = 20;
103
    const PAPERSIZE_NO11_ENVELOPE = 21;
104
    const PAPERSIZE_NO12_ENVELOPE = 22;
105
    const PAPERSIZE_NO14_ENVELOPE = 23;
106
    const PAPERSIZE_C = 24;
107
    const PAPERSIZE_D = 25;
108
    const PAPERSIZE_E = 26;
109
    const PAPERSIZE_DL_ENVELOPE = 27;
110
    const PAPERSIZE_C5_ENVELOPE = 28;
111
    const PAPERSIZE_C3_ENVELOPE = 29;
112
    const PAPERSIZE_C4_ENVELOPE = 30;
113
    const PAPERSIZE_C6_ENVELOPE = 31;
114
    const PAPERSIZE_C65_ENVELOPE = 32;
115
    const PAPERSIZE_B4_ENVELOPE = 33;
116
    const PAPERSIZE_B5_ENVELOPE = 34;
117
    const PAPERSIZE_B6_ENVELOPE = 35;
118
    const PAPERSIZE_ITALY_ENVELOPE = 36;
119
    const PAPERSIZE_MONARCH_ENVELOPE = 37;
120
    const PAPERSIZE_6_3_4_ENVELOPE = 38;
121
    const PAPERSIZE_US_STANDARD_FANFOLD = 39;
122
    const PAPERSIZE_GERMAN_STANDARD_FANFOLD = 40;
123
    const PAPERSIZE_GERMAN_LEGAL_FANFOLD = 41;
124
    const PAPERSIZE_ISO_B4 = 42;
125
    const PAPERSIZE_JAPANESE_DOUBLE_POSTCARD = 43;
126
    const PAPERSIZE_STANDARD_PAPER_1 = 44;
127
    const PAPERSIZE_STANDARD_PAPER_2 = 45;
128
    const PAPERSIZE_STANDARD_PAPER_3 = 46;
129
    const PAPERSIZE_INVITE_ENVELOPE = 47;
130
    const PAPERSIZE_LETTER_EXTRA_PAPER = 48;
131
    const PAPERSIZE_LEGAL_EXTRA_PAPER = 49;
132
    const PAPERSIZE_TABLOID_EXTRA_PAPER = 50;
133
    const PAPERSIZE_A4_EXTRA_PAPER = 51;
134
    const PAPERSIZE_LETTER_TRANSVERSE_PAPER = 52;
135
    const PAPERSIZE_A4_TRANSVERSE_PAPER = 53;
136
    const PAPERSIZE_LETTER_EXTRA_TRANSVERSE_PAPER = 54;
137
    const PAPERSIZE_SUPERA_SUPERA_A4_PAPER = 55;
138
    const PAPERSIZE_SUPERB_SUPERB_A3_PAPER = 56;
139
    const PAPERSIZE_LETTER_PLUS_PAPER = 57;
140
    const PAPERSIZE_A4_PLUS_PAPER = 58;
141
    const PAPERSIZE_A5_TRANSVERSE_PAPER = 59;
142
    const PAPERSIZE_JIS_B5_TRANSVERSE_PAPER = 60;
143
    const PAPERSIZE_A3_EXTRA_PAPER = 61;
144
    const PAPERSIZE_A5_EXTRA_PAPER = 62;
145
    const PAPERSIZE_ISO_B5_EXTRA_PAPER = 63;
146
    const PAPERSIZE_A2_PAPER = 64;
147
    const PAPERSIZE_A3_TRANSVERSE_PAPER = 65;
148
    const PAPERSIZE_A3_EXTRA_TRANSVERSE_PAPER = 66;
149
 
150
    // Page orientation
151
    const ORIENTATION_DEFAULT = 'default';
152
    const ORIENTATION_LANDSCAPE = 'landscape';
153
    const ORIENTATION_PORTRAIT = 'portrait';
154
 
155
    // Print Range Set Method
156
    const SETPRINTRANGE_OVERWRITE = 'O';
157
    const SETPRINTRANGE_INSERT = 'I';
158
 
159
    const PAGEORDER_OVER_THEN_DOWN = 'overThenDown';
160
    const PAGEORDER_DOWN_THEN_OVER = 'downThenOver';
161
 
162
    /**
163
     * Paper size default.
164
     */
165
    private static int $paperSizeDefault = self::PAPERSIZE_LETTER;
166
 
167
    /**
168
     * Paper size.
169
     */
170
    private ?int $paperSize = null;
171
 
172
    /**
173
     * Orientation default.
174
     */
175
    private static string $orientationDefault = self::ORIENTATION_DEFAULT;
176
 
177
    /**
178
     * Orientation.
179
     */
180
    private string $orientation;
181
 
182
    /**
183
     * Scale (Print Scale).
184
     *
185
     * Print scaling. Valid values range from 10 to 400
186
     * This setting is overridden when fitToWidth and/or fitToHeight are in use
187
     */
188
    private ?int $scale = 100;
189
 
190
    /**
191
     * Fit To Page
192
     * Whether scale or fitToWith / fitToHeight applies.
193
     */
194
    private bool $fitToPage = false;
195
 
196
    /**
197
     * Fit To Height
198
     * Number of vertical pages to fit on.
199
     */
200
    private ?int $fitToHeight = 1;
201
 
202
    /**
203
     * Fit To Width
204
     * Number of horizontal pages to fit on.
205
     */
206
    private ?int $fitToWidth = 1;
207
 
208
    /**
209
     * Columns to repeat at left.
210
     *
211
     * @var array Containing start column and end column, empty array if option unset
212
     */
213
    private array $columnsToRepeatAtLeft = ['', ''];
214
 
215
    /**
216
     * Rows to repeat at top.
217
     *
218
     * @var array Containing start row number and end row number, empty array if option unset
219
     */
220
    private array $rowsToRepeatAtTop = [0, 0];
221
 
222
    /**
223
     * Center page horizontally.
224
     */
225
    private bool $horizontalCentered = false;
226
 
227
    /**
228
     * Center page vertically.
229
     */
230
    private bool $verticalCentered = false;
231
 
232
    /**
233
     * Print area.
234
     */
235
    private ?string $printArea = null;
236
 
237
    /**
238
     * First page number.
239
     */
240
    private ?int $firstPageNumber = null;
241
 
242
    private string $pageOrder = self::PAGEORDER_DOWN_THEN_OVER;
243
 
244
    /**
245
     * Create a new PageSetup.
246
     */
247
    public function __construct()
248
    {
249
        $this->orientation = self::$orientationDefault;
250
    }
251
 
252
    /**
253
     * Get Paper Size.
254
     */
255
    public function getPaperSize(): int
256
    {
257
        return $this->paperSize ?? self::$paperSizeDefault;
258
    }
259
 
260
    /**
261
     * Set Paper Size.
262
     *
263
     * @param int $paperSize see self::PAPERSIZE_*
264
     *
265
     * @return $this
266
     */
267
    public function setPaperSize(int $paperSize): static
268
    {
269
        $this->paperSize = $paperSize;
270
 
271
        return $this;
272
    }
273
 
274
    /**
275
     * Get Paper Size default.
276
     */
277
    public static function getPaperSizeDefault(): int
278
    {
279
        return self::$paperSizeDefault;
280
    }
281
 
282
    /**
283
     * Set Paper Size Default.
284
     */
285
    public static function setPaperSizeDefault(int $paperSize): void
286
    {
287
        self::$paperSizeDefault = $paperSize;
288
    }
289
 
290
    /**
291
     * Get Orientation.
292
     */
293
    public function getOrientation(): string
294
    {
295
        return $this->orientation;
296
    }
297
 
298
    /**
299
     * Set Orientation.
300
     *
301
     * @param string $orientation see self::ORIENTATION_*
302
     *
303
     * @return $this
304
     */
305
    public function setOrientation(string $orientation): static
306
    {
307
        if ($orientation === self::ORIENTATION_LANDSCAPE || $orientation === self::ORIENTATION_PORTRAIT || $orientation === self::ORIENTATION_DEFAULT) {
308
            $this->orientation = $orientation;
309
        }
310
 
311
        return $this;
312
    }
313
 
314
    public static function getOrientationDefault(): string
315
    {
316
        return self::$orientationDefault;
317
    }
318
 
319
    public static function setOrientationDefault(string $orientation): void
320
    {
321
        if ($orientation === self::ORIENTATION_LANDSCAPE || $orientation === self::ORIENTATION_PORTRAIT || $orientation === self::ORIENTATION_DEFAULT) {
322
            self::$orientationDefault = $orientation;
323
        }
324
    }
325
 
326
    /**
327
     * Get Scale.
328
     */
329
    public function getScale(): ?int
330
    {
331
        return $this->scale;
332
    }
333
 
334
    /**
335
     * Set Scale.
336
     * Print scaling. Valid values range from 10 to 400
337
     * This setting is overridden when fitToWidth and/or fitToHeight are in use.
338
     *
339
     * @param bool $update Update fitToPage so scaling applies rather than fitToHeight / fitToWidth
340
     *
341
     * @return $this
342
     */
343
    public function setScale(?int $scale, bool $update = true): static
344
    {
345
        // Microsoft Office Excel 2007 only allows setting a scale between 10 and 400 via the user interface,
346
        // but it is apparently still able to handle any scale >= 0, where 0 results in 100
347
        if ($scale === null || $scale >= 0) {
348
            $this->scale = $scale;
349
            if ($update) {
350
                $this->fitToPage = false;
351
            }
352
        } else {
353
            throw new PhpSpreadsheetException('Scale must not be negative');
354
        }
355
 
356
        return $this;
357
    }
358
 
359
    /**
360
     * Get Fit To Page.
361
     */
362
    public function getFitToPage(): bool
363
    {
364
        return $this->fitToPage;
365
    }
366
 
367
    /**
368
     * Set Fit To Page.
369
     *
370
     * @return $this
371
     */
372
    public function setFitToPage(bool $fitToPage): static
373
    {
374
        $this->fitToPage = $fitToPage;
375
 
376
        return $this;
377
    }
378
 
379
    /**
380
     * Get Fit To Height.
381
     */
382
    public function getFitToHeight(): ?int
383
    {
384
        return $this->fitToHeight;
385
    }
386
 
387
    /**
388
     * Set Fit To Height.
389
     *
390
     * @param bool $update Update fitToPage so it applies rather than scaling
391
     *
392
     * @return $this
393
     */
394
    public function setFitToHeight(?int $fitToHeight, bool $update = true): static
395
    {
396
        $this->fitToHeight = $fitToHeight;
397
        if ($update) {
398
            $this->fitToPage = true;
399
        }
400
 
401
        return $this;
402
    }
403
 
404
    /**
405
     * Get Fit To Width.
406
     */
407
    public function getFitToWidth(): ?int
408
    {
409
        return $this->fitToWidth;
410
    }
411
 
412
    /**
413
     * Set Fit To Width.
414
     *
415
     * @param bool $update Update fitToPage so it applies rather than scaling
416
     *
417
     * @return $this
418
     */
419
    public function setFitToWidth(?int $value, bool $update = true): static
420
    {
421
        $this->fitToWidth = $value;
422
        if ($update) {
423
            $this->fitToPage = true;
424
        }
425
 
426
        return $this;
427
    }
428
 
429
    /**
430
     * Is Columns to repeat at left set?
431
     */
432
    public function isColumnsToRepeatAtLeftSet(): bool
433
    {
434
        if (!empty($this->columnsToRepeatAtLeft)) {
435
            if ($this->columnsToRepeatAtLeft[0] != '' && $this->columnsToRepeatAtLeft[1] != '') {
436
                return true;
437
            }
438
        }
439
 
440
        return false;
441
    }
442
 
443
    /**
444
     * Get Columns to repeat at left.
445
     *
446
     * @return array Containing start column and end column, empty array if option unset
447
     */
448
    public function getColumnsToRepeatAtLeft(): array
449
    {
450
        return $this->columnsToRepeatAtLeft;
451
    }
452
 
453
    /**
454
     * Set Columns to repeat at left.
455
     *
456
     * @param array $columnsToRepeatAtLeft Containing start column and end column, empty array if option unset
457
     *
458
     * @return $this
459
     */
460
    public function setColumnsToRepeatAtLeft(array $columnsToRepeatAtLeft): static
461
    {
462
        $this->columnsToRepeatAtLeft = $columnsToRepeatAtLeft;
463
 
464
        return $this;
465
    }
466
 
467
    /**
468
     * Set Columns to repeat at left by start and end.
469
     *
470
     * @param string $start eg: 'A'
471
     * @param string $end eg: 'B'
472
     *
473
     * @return $this
474
     */
475
    public function setColumnsToRepeatAtLeftByStartAndEnd(string $start, string $end): static
476
    {
477
        $this->columnsToRepeatAtLeft = [$start, $end];
478
 
479
        return $this;
480
    }
481
 
482
    /**
483
     * Is Rows to repeat at top set?
484
     */
485
    public function isRowsToRepeatAtTopSet(): bool
486
    {
487
        if (!empty($this->rowsToRepeatAtTop)) {
488
            if ($this->rowsToRepeatAtTop[0] != 0 && $this->rowsToRepeatAtTop[1] != 0) {
489
                return true;
490
            }
491
        }
492
 
493
        return false;
494
    }
495
 
496
    /**
497
     * Get Rows to repeat at top.
498
     *
499
     * @return array Containing start column and end column, empty array if option unset
500
     */
501
    public function getRowsToRepeatAtTop(): array
502
    {
503
        return $this->rowsToRepeatAtTop;
504
    }
505
 
506
    /**
507
     * Set Rows to repeat at top.
508
     *
509
     * @param array $rowsToRepeatAtTop Containing start column and end column, empty array if option unset
510
     *
511
     * @return $this
512
     */
513
    public function setRowsToRepeatAtTop(array $rowsToRepeatAtTop): static
514
    {
515
        $this->rowsToRepeatAtTop = $rowsToRepeatAtTop;
516
 
517
        return $this;
518
    }
519
 
520
    /**
521
     * Set Rows to repeat at top by start and end.
522
     *
523
     * @param int $start eg: 1
524
     * @param int $end eg: 1
525
     *
526
     * @return $this
527
     */
528
    public function setRowsToRepeatAtTopByStartAndEnd(int $start, int $end): static
529
    {
530
        $this->rowsToRepeatAtTop = [$start, $end];
531
 
532
        return $this;
533
    }
534
 
535
    /**
536
     * Get center page horizontally.
537
     */
538
    public function getHorizontalCentered(): bool
539
    {
540
        return $this->horizontalCentered;
541
    }
542
 
543
    /**
544
     * Set center page horizontally.
545
     *
546
     * @return $this
547
     */
548
    public function setHorizontalCentered(bool $value): static
549
    {
550
        $this->horizontalCentered = $value;
551
 
552
        return $this;
553
    }
554
 
555
    /**
556
     * Get center page vertically.
557
     */
558
    public function getVerticalCentered(): bool
559
    {
560
        return $this->verticalCentered;
561
    }
562
 
563
    /**
564
     * Set center page vertically.
565
     *
566
     * @return $this
567
     */
568
    public function setVerticalCentered(bool $value): static
569
    {
570
        $this->verticalCentered = $value;
571
 
572
        return $this;
573
    }
574
 
575
    /**
576
     * Get print area.
577
     *
578
     * @param int $index Identifier for a specific print area range if several ranges have been set
579
     *                            Default behaviour, or a index value of 0, will return all ranges as a comma-separated string
580
     *                            Otherwise, the specific range identified by the value of $index will be returned
581
     *                            Print areas are numbered from 1
582
     */
583
    public function getPrintArea(int $index = 0): string
584
    {
585
        if ($index == 0) {
586
            return (string) $this->printArea;
587
        }
588
        $printAreas = explode(',', (string) $this->printArea);
589
        if (isset($printAreas[$index - 1])) {
590
            return $printAreas[$index - 1];
591
        }
592
 
593
        throw new PhpSpreadsheetException('Requested Print Area does not exist');
594
    }
595
 
596
    /**
597
     * Is print area set?
598
     *
599
     * @param int $index Identifier for a specific print area range if several ranges have been set
600
     *                            Default behaviour, or an index value of 0, will identify whether any print range is set
601
     *                            Otherwise, existence of the range identified by the value of $index will be returned
602
     *                            Print areas are numbered from 1
603
     */
604
    public function isPrintAreaSet(int $index = 0): bool
605
    {
606
        if ($index == 0) {
607
            return $this->printArea !== null;
608
        }
609
        $printAreas = explode(',', (string) $this->printArea);
610
 
611
        return isset($printAreas[$index - 1]);
612
    }
613
 
614
    /**
615
     * Clear a print area.
616
     *
617
     * @param int $index Identifier for a specific print area range if several ranges have been set
618
     *                            Default behaviour, or an index value of 0, will clear all print ranges that are set
619
     *                            Otherwise, the range identified by the value of $index will be removed from the series
620
     *                            Print areas are numbered from 1
621
     *
622
     * @return $this
623
     */
624
    public function clearPrintArea(int $index = 0): static
625
    {
626
        if ($index == 0) {
627
            $this->printArea = null;
628
        } else {
629
            $printAreas = explode(',', (string) $this->printArea);
630
            if (isset($printAreas[$index - 1])) {
631
                unset($printAreas[$index - 1]);
632
                $this->printArea = implode(',', $printAreas);
633
            }
634
        }
635
 
636
        return $this;
637
    }
638
 
639
    /**
640
     * Set print area. e.g. 'A1:D10' or 'A1:D10,G5:M20'.
641
     *
642
     * @param int $index Identifier for a specific print area range allowing several ranges to be set
643
     *                            When the method is "O"verwrite, then a positive integer index will overwrite that indexed
644
     *                                entry in the print areas list; a negative index value will identify which entry to
645
     *                                overwrite working bacward through the print area to the list, with the last entry as -1.
646
     *                                Specifying an index value of 0, will overwrite <b>all</b> existing print ranges.
647
     *                            When the method is "I"nsert, then a positive index will insert after that indexed entry in
648
     *                                the print areas list, while a negative index will insert before the indexed entry.
649
     *                                Specifying an index value of 0, will always append the new print range at the end of the
650
     *                                list.
651
     *                            Print areas are numbered from 1
652
     * @param string $method Determines the method used when setting multiple print areas
653
     *                            Default behaviour, or the "O" method, overwrites existing print area
654
     *                            The "I" method, inserts the new print area before any specified index, or at the end of the list
655
     *
656
     * @return $this
657
     */
658
    public function setPrintArea(string $value, int $index = 0, string $method = self::SETPRINTRANGE_OVERWRITE): static
659
    {
660
        if (str_contains($value, '!')) {
661
            throw new PhpSpreadsheetException('Cell coordinate must not specify a worksheet.');
662
        } elseif (!str_contains($value, ':')) {
663
            throw new PhpSpreadsheetException('Cell coordinate must be a range of cells.');
664
        } elseif (str_contains($value, '$')) {
665
            throw new PhpSpreadsheetException('Cell coordinate must not be absolute.');
666
        }
667
        $value = strtoupper($value);
668
        if (!$this->printArea) {
669
            $index = 0;
670
        }
671
 
672
        if ($method == self::SETPRINTRANGE_OVERWRITE) {
673
            if ($index == 0) {
674
                $this->printArea = $value;
675
            } else {
676
                $printAreas = explode(',', (string) $this->printArea);
677
                if ($index < 0) {
678
                    $index = count($printAreas) - abs($index) + 1;
679
                }
680
                if (($index <= 0) || ($index > count($printAreas))) {
681
                    throw new PhpSpreadsheetException('Invalid index for setting print range.');
682
                }
683
                $printAreas[$index - 1] = $value;
684
                $this->printArea = implode(',', $printAreas);
685
            }
686
        } elseif ($method == self::SETPRINTRANGE_INSERT) {
687
            if ($index == 0) {
688
                $this->printArea = $this->printArea ? ($this->printArea . ',' . $value) : $value;
689
            } else {
690
                $printAreas = explode(',', (string) $this->printArea);
691
                if ($index < 0) {
692
                    $index = (int) abs($index) - 1;
693
                }
694
                if ($index > count($printAreas)) {
695
                    throw new PhpSpreadsheetException('Invalid index for setting print range.');
696
                }
697
                $printAreas = array_merge(array_slice($printAreas, 0, $index), [$value], array_slice($printAreas, $index));
698
                $this->printArea = implode(',', $printAreas);
699
            }
700
        } else {
701
            throw new PhpSpreadsheetException('Invalid method for setting print range.');
702
        }
703
 
704
        return $this;
705
    }
706
 
707
    /**
708
     * Add a new print area (e.g. 'A1:D10' or 'A1:D10,G5:M20') to the list of print areas.
709
     *
710
     * @param int $index Identifier for a specific print area range allowing several ranges to be set
711
     *                            A positive index will insert after that indexed entry in the print areas list, while a
712
     *                                negative index will insert before the indexed entry.
713
     *                                Specifying an index value of 0, will always append the new print range at the end of the
714
     *                                list.
715
     *                            Print areas are numbered from 1
716
     *
717
     * @return $this
718
     */
719
    public function addPrintArea(string $value, int $index = -1): static
720
    {
721
        return $this->setPrintArea($value, $index, self::SETPRINTRANGE_INSERT);
722
    }
723
 
724
    /**
725
     * Set print area.
726
     *
727
     * @param int $column1 Column 1
728
     * @param int $row1 Row 1
729
     * @param int $column2 Column 2
730
     * @param int $row2 Row 2
731
     * @param int $index Identifier for a specific print area range allowing several ranges to be set
732
     *                                When the method is "O"verwrite, then a positive integer index will overwrite that indexed
733
     *                                    entry in the print areas list; a negative index value will identify which entry to
734
     *                                    overwrite working backward through the print area to the list, with the last entry as -1.
735
     *                                    Specifying an index value of 0, will overwrite <b>all</b> existing print ranges.
736
     *                                When the method is "I"nsert, then a positive index will insert after that indexed entry in
737
     *                                    the print areas list, while a negative index will insert before the indexed entry.
738
     *                                    Specifying an index value of 0, will always append the new print range at the end of the
739
     *                                    list.
740
     *                                Print areas are numbered from 1
741
     * @param string $method Determines the method used when setting multiple print areas
742
     *                                Default behaviour, or the "O" method, overwrites existing print area
743
     *                                The "I" method, inserts the new print area before any specified index, or at the end of the list
744
     *
745
     * @return $this
746
     */
747
    public function setPrintAreaByColumnAndRow(int $column1, int $row1, int $column2, int $row2, int $index = 0, string $method = self::SETPRINTRANGE_OVERWRITE): static
748
    {
749
        return $this->setPrintArea(
750
            Coordinate::stringFromColumnIndex($column1) . $row1 . ':' . Coordinate::stringFromColumnIndex($column2) . $row2,
751
            $index,
752
            $method
753
        );
754
    }
755
 
756
    /**
757
     * Add a new print area to the list of print areas.
758
     *
759
     * @param int $column1 Start Column for the print area
760
     * @param int $row1 Start Row for the print area
761
     * @param int $column2 End Column for the print area
762
     * @param int $row2 End Row for the print area
763
     * @param int $index Identifier for a specific print area range allowing several ranges to be set
764
     *                                A positive index will insert after that indexed entry in the print areas list, while a
765
     *                                    negative index will insert before the indexed entry.
766
     *                                    Specifying an index value of 0, will always append the new print range at the end of the
767
     *                                    list.
768
     *                                Print areas are numbered from 1
769
     *
770
     * @return $this
771
     */
772
    public function addPrintAreaByColumnAndRow(int $column1, int $row1, int $column2, int $row2, int $index = -1): static
773
    {
774
        return $this->setPrintArea(
775
            Coordinate::stringFromColumnIndex($column1) . $row1 . ':' . Coordinate::stringFromColumnIndex($column2) . $row2,
776
            $index,
777
            self::SETPRINTRANGE_INSERT
778
        );
779
    }
780
 
781
    /**
782
     * Get first page number.
783
     */
784
    public function getFirstPageNumber(): ?int
785
    {
786
        return $this->firstPageNumber;
787
    }
788
 
789
    /**
790
     * Set first page number.
791
     *
792
     * @return $this
793
     */
794
    public function setFirstPageNumber(?int $value): static
795
    {
796
        $this->firstPageNumber = $value;
797
 
798
        return $this;
799
    }
800
 
801
    /**
802
     * Reset first page number.
803
     *
804
     * @return $this
805
     */
806
    public function resetFirstPageNumber(): static
807
    {
808
        return $this->setFirstPageNumber(null);
809
    }
810
 
811
    public function getPageOrder(): string
812
    {
813
        return $this->pageOrder;
814
    }
815
 
816
    public function setPageOrder(?string $pageOrder): self
817
    {
818
        if ($pageOrder === null || $pageOrder === self::PAGEORDER_DOWN_THEN_OVER || $pageOrder === self::PAGEORDER_OVER_THEN_DOWN) {
819
            $this->pageOrder = $pageOrder ?? self::PAGEORDER_DOWN_THEN_OVER;
820
        }
821
 
822
        return $this;
823
    }
824
}