CellAddress.php 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. <?php
  2. namespace PhpOffice\PhpSpreadsheet\Cell;
  3. use PhpOffice\PhpSpreadsheet\Exception;
  4. use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
  5. class CellAddress
  6. {
  7. /**
  8. * @var ?Worksheet
  9. */
  10. protected $worksheet;
  11. /**
  12. * @var string
  13. */
  14. protected $cellAddress;
  15. /**
  16. * @var string
  17. */
  18. protected $columnName;
  19. /**
  20. * @var int
  21. */
  22. protected $columnId;
  23. /**
  24. * @var int
  25. */
  26. protected $rowId;
  27. public function __construct(string $cellAddress, ?Worksheet $worksheet = null)
  28. {
  29. $this->cellAddress = str_replace('$', '', $cellAddress);
  30. [$this->columnId, $this->rowId, $this->columnName] = Coordinate::indexesFromString($this->cellAddress);
  31. $this->worksheet = $worksheet;
  32. }
  33. /**
  34. * @param mixed $columnId
  35. * @param mixed $rowId
  36. */
  37. private static function validateColumnAndRow($columnId, $rowId): void
  38. {
  39. if (!is_numeric($columnId) || $columnId <= 0 || !is_numeric($rowId) || $rowId <= 0) {
  40. throw new Exception('Row and Column Ids must be positive integer values');
  41. }
  42. }
  43. /**
  44. * @param mixed $columnId
  45. * @param mixed $rowId
  46. */
  47. public static function fromColumnAndRow($columnId, $rowId, ?Worksheet $worksheet = null): self
  48. {
  49. self::validateColumnAndRow($columnId, $rowId);
  50. /** @phpstan-ignore-next-line */
  51. return new static(Coordinate::stringFromColumnIndex($columnId) . ((string) $rowId), $worksheet);
  52. }
  53. public static function fromColumnRowArray(array $array, ?Worksheet $worksheet = null): self
  54. {
  55. [$columnId, $rowId] = $array;
  56. return static::fromColumnAndRow($columnId, $rowId, $worksheet);
  57. }
  58. /**
  59. * @param mixed $cellAddress
  60. */
  61. public static function fromCellAddress($cellAddress, ?Worksheet $worksheet = null): self
  62. {
  63. /** @phpstan-ignore-next-line */
  64. return new static($cellAddress, $worksheet);
  65. }
  66. /**
  67. * The returned address string will contain the worksheet name as well, if available,
  68. * (ie. if a Worksheet was provided to the constructor).
  69. * e.g. "'Mark''s Worksheet'!C5".
  70. */
  71. public function fullCellAddress(): string
  72. {
  73. if ($this->worksheet !== null) {
  74. $title = str_replace("'", "''", $this->worksheet->getTitle());
  75. return "'{$title}'!{$this->cellAddress}";
  76. }
  77. return $this->cellAddress;
  78. }
  79. public function worksheet(): ?Worksheet
  80. {
  81. return $this->worksheet;
  82. }
  83. /**
  84. * The returned address string will contain just the column/row address,
  85. * (even if a Worksheet was provided to the constructor).
  86. * e.g. "C5".
  87. */
  88. public function cellAddress(): string
  89. {
  90. return $this->cellAddress;
  91. }
  92. public function rowId(): int
  93. {
  94. return $this->rowId;
  95. }
  96. public function columnId(): int
  97. {
  98. return $this->columnId;
  99. }
  100. public function columnName(): string
  101. {
  102. return $this->columnName;
  103. }
  104. public function nextRow(int $offset = 1): self
  105. {
  106. $newRowId = $this->rowId + $offset;
  107. if ($newRowId < 1) {
  108. $newRowId = 1;
  109. }
  110. return static::fromColumnAndRow($this->columnId, $newRowId);
  111. }
  112. public function previousRow(int $offset = 1): self
  113. {
  114. return $this->nextRow(0 - $offset);
  115. }
  116. public function nextColumn(int $offset = 1): self
  117. {
  118. $newColumnId = $this->columnId + $offset;
  119. if ($newColumnId < 1) {
  120. $newColumnId = 1;
  121. }
  122. return static::fromColumnAndRow($newColumnId, $this->rowId);
  123. }
  124. public function previousColumn(int $offset = 1): self
  125. {
  126. return $this->nextColumn(0 - $offset);
  127. }
  128. /**
  129. * The returned address string will contain the worksheet name as well, if available,
  130. * (ie. if a Worksheet was provided to the constructor).
  131. * e.g. "'Mark''s Worksheet'!C5".
  132. */
  133. public function __toString()
  134. {
  135. return $this->fullCellAddress();
  136. }
  137. }