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\Cell;
6
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
7
use PhpOffice\PhpSpreadsheet\Exception as PhpSpreadsheetException;
8
 
9
/**
10
 * @extends CellIterator<int>
11
 */
12
class ColumnCellIterator extends CellIterator
13
{
14
    /**
15
     * Current iterator position.
16
     */
17
    private int $currentRow;
18
 
19
    /**
20
     * Column index.
21
     */
22
    private int $columnIndex;
23
 
24
    /**
25
     * Start position.
26
     */
27
    private int $startRow = 1;
28
 
29
    /**
30
     * End position.
31
     */
32
    private int $endRow = 1;
33
 
34
    /**
35
     * Create a new row iterator.
36
     *
37
     * @param Worksheet $worksheet The worksheet to iterate over
38
     * @param string $columnIndex The column that we want to iterate
39
     * @param int $startRow The row number at which to start iterating
40
     * @param ?int $endRow Optionally, the row number at which to stop iterating
41
     */
42
    public function __construct(Worksheet $worksheet, string $columnIndex = 'A', int $startRow = 1, ?int $endRow = null, bool $iterateOnlyExistingCells = false)
43
    {
44
        // Set subject
45
        $this->worksheet = $worksheet;
46
        $this->cellCollection = $worksheet->getCellCollection();
47
        $this->columnIndex = Coordinate::columnIndexFromString($columnIndex);
48
        $this->resetEnd($endRow);
49
        $this->resetStart($startRow);
50
        $this->setIterateOnlyExistingCells($iterateOnlyExistingCells);
51
    }
52
 
53
    /**
54
     * (Re)Set the start row and the current row pointer.
55
     *
56
     * @param int $startRow The row number at which to start iterating
57
     *
58
     * @return $this
59
     */
60
    public function resetStart(int $startRow = 1): static
61
    {
62
        $this->startRow = $startRow;
63
        $this->adjustForExistingOnlyRange();
64
        $this->seek($startRow);
65
 
66
        return $this;
67
    }
68
 
69
    /**
70
     * (Re)Set the end row.
71
     *
72
     * @param ?int $endRow The row number at which to stop iterating
73
     *
74
     * @return $this
75
     */
76
    public function resetEnd(?int $endRow = null): static
77
    {
78
        $this->endRow = $endRow ?: $this->worksheet->getHighestRow();
79
        $this->adjustForExistingOnlyRange();
80
 
81
        return $this;
82
    }
83
 
84
    /**
85
     * Set the row pointer to the selected row.
86
     *
87
     * @param int $row The row number to set the current pointer at
88
     *
89
     * @return $this
90
     */
91
    public function seek(int $row = 1): static
92
    {
93
        if (
94
            $this->onlyExistingCells
95
            && (!$this->cellCollection->has(Coordinate::stringFromColumnIndex($this->columnIndex) . $row))
96
        ) {
97
            throw new PhpSpreadsheetException('In "IterateOnlyExistingCells" mode and Cell does not exist');
98
        }
99
        if (($row < $this->startRow) || ($row > $this->endRow)) {
100
            throw new PhpSpreadsheetException("Row $row is out of range ({$this->startRow} - {$this->endRow})");
101
        }
102
        $this->currentRow = $row;
103
 
104
        return $this;
105
    }
106
 
107
    /**
108
     * Rewind the iterator to the starting row.
109
     */
110
    public function rewind(): void
111
    {
112
        $this->currentRow = $this->startRow;
113
    }
114
 
115
    /**
116
     * Return the current cell in this worksheet column.
117
     */
118
    public function current(): ?Cell
119
    {
120
        $cellAddress = Coordinate::stringFromColumnIndex($this->columnIndex) . $this->currentRow;
121
 
122
        return $this->cellCollection->has($cellAddress)
123
            ? $this->cellCollection->get($cellAddress)
124
            : (
125
                $this->ifNotExists === self::IF_NOT_EXISTS_CREATE_NEW
126
                ? $this->worksheet->createNewCell($cellAddress)
127
                : null
128
            );
129
    }
130
 
131
    /**
132
     * Return the current iterator key.
133
     */
134
    public function key(): int
135
    {
136
        return $this->currentRow;
137
    }
138
 
139
    /**
140
     * Set the iterator to its next value.
141
     */
142
    public function next(): void
143
    {
144
        $columnAddress = Coordinate::stringFromColumnIndex($this->columnIndex);
145
        do {
146
            ++$this->currentRow;
147
        } while (
148
            ($this->onlyExistingCells)
149
            && ($this->currentRow <= $this->endRow)
150
            && (!$this->cellCollection->has($columnAddress . $this->currentRow))
151
        );
152
    }
153
 
154
    /**
155
     * Set the iterator to its previous value.
156
     */
157
    public function prev(): void
158
    {
159
        $columnAddress = Coordinate::stringFromColumnIndex($this->columnIndex);
160
        do {
161
            --$this->currentRow;
162
        } while (
163
            ($this->onlyExistingCells)
164
            && ($this->currentRow >= $this->startRow)
165
            && (!$this->cellCollection->has($columnAddress . $this->currentRow))
166
        );
167
    }
168
 
169
    /**
170
     * Indicate if more rows exist in the worksheet range of rows that we're iterating.
171
     */
172
    public function valid(): bool
173
    {
174
        return $this->currentRow <= $this->endRow && $this->currentRow >= $this->startRow;
175
    }
176
 
177
    /**
178
     * Validate start/end values for "IterateOnlyExistingCells" mode, and adjust if necessary.
179
     */
180
    protected function adjustForExistingOnlyRange(): void
181
    {
182
        if ($this->onlyExistingCells) {
183
            $columnAddress = Coordinate::stringFromColumnIndex($this->columnIndex);
184
            while (
185
                (!$this->cellCollection->has($columnAddress . $this->startRow))
186
                && ($this->startRow <= $this->endRow)
187
            ) {
188
                ++$this->startRow;
189
            }
190
            while (
191
                (!$this->cellCollection->has($columnAddress . $this->endRow))
192
                && ($this->endRow >= $this->startRow)
193
            ) {
194
                --$this->endRow;
195
            }
196
        }
197
    }
198
}