RowCellIterator.php 6.1 KB

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