CellReferenceHelper.php 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. <?php
  2. namespace PhpOffice\PhpSpreadsheet;
  3. use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
  4. class CellReferenceHelper
  5. {
  6. /**
  7. * @var string
  8. */
  9. protected $beforeCellAddress;
  10. /**
  11. * @var int
  12. */
  13. protected $beforeColumn;
  14. /**
  15. * @var int
  16. */
  17. protected $beforeRow;
  18. /**
  19. * @var int
  20. */
  21. protected $numberOfColumns;
  22. /**
  23. * @var int
  24. */
  25. protected $numberOfRows;
  26. public function __construct(string $beforeCellAddress = 'A1', int $numberOfColumns = 0, int $numberOfRows = 0)
  27. {
  28. $this->beforeCellAddress = str_replace('$', '', $beforeCellAddress);
  29. $this->numberOfColumns = $numberOfColumns;
  30. $this->numberOfRows = $numberOfRows;
  31. // Get coordinate of $beforeCellAddress
  32. [$beforeColumn, $beforeRow] = Coordinate::coordinateFromString($beforeCellAddress);
  33. $this->beforeColumn = (int) Coordinate::columnIndexFromString($beforeColumn);
  34. $this->beforeRow = (int) $beforeRow;
  35. }
  36. public function beforeCellAddress(): string
  37. {
  38. return $this->beforeCellAddress;
  39. }
  40. public function refreshRequired(string $beforeCellAddress, int $numberOfColumns, int $numberOfRows): bool
  41. {
  42. return $this->beforeCellAddress !== $beforeCellAddress ||
  43. $this->numberOfColumns !== $numberOfColumns ||
  44. $this->numberOfRows !== $numberOfRows;
  45. }
  46. public function updateCellReference(string $cellReference = 'A1', bool $includeAbsoluteReferences = false): string
  47. {
  48. if (Coordinate::coordinateIsRange($cellReference)) {
  49. throw new Exception('Only single cell references may be passed to this method.');
  50. }
  51. // Get coordinate of $cellReference
  52. [$newColumn, $newRow] = Coordinate::coordinateFromString($cellReference);
  53. $newColumnIndex = (int) Coordinate::columnIndexFromString(str_replace('$', '', $newColumn));
  54. $newRowIndex = (int) str_replace('$', '', $newRow);
  55. $absoluteColumn = $newColumn[0] === '$' ? '$' : '';
  56. $absoluteRow = $newRow[0] === '$' ? '$' : '';
  57. // Verify which parts should be updated
  58. if ($includeAbsoluteReferences === false) {
  59. $updateColumn = (($absoluteColumn !== '$') && $newColumnIndex >= $this->beforeColumn);
  60. $updateRow = (($absoluteRow !== '$') && $newRowIndex >= $this->beforeRow);
  61. } else {
  62. $updateColumn = ($newColumnIndex >= $this->beforeColumn);
  63. $updateRow = ($newRowIndex >= $this->beforeRow);
  64. }
  65. // Create new column reference
  66. if ($updateColumn) {
  67. $newColumn = ($includeAbsoluteReferences === false)
  68. ? Coordinate::stringFromColumnIndex($newColumnIndex + $this->numberOfColumns)
  69. : $absoluteColumn . Coordinate::stringFromColumnIndex($newColumnIndex + $this->numberOfColumns);
  70. }
  71. // Create new row reference
  72. if ($updateRow) {
  73. $newRow = ($includeAbsoluteReferences === false)
  74. ? $newRowIndex + $this->numberOfRows
  75. : $absoluteRow . (string) ($newRowIndex + $this->numberOfRows);
  76. }
  77. // Return new reference
  78. return "{$newColumn}{$newRow}";
  79. }
  80. public function cellAddressInDeleteRange(string $cellAddress): bool
  81. {
  82. [$cellColumn, $cellRow] = Coordinate::coordinateFromString($cellAddress);
  83. $cellColumnIndex = Coordinate::columnIndexFromString($cellColumn);
  84. // Is cell within the range of rows/columns if we're deleting
  85. if (
  86. $this->numberOfRows < 0 &&
  87. ($cellRow >= ($this->beforeRow + $this->numberOfRows)) &&
  88. ($cellRow < $this->beforeRow)
  89. ) {
  90. return true;
  91. } elseif (
  92. $this->numberOfColumns < 0 &&
  93. ($cellColumnIndex >= ($this->beforeColumn + $this->numberOfColumns)) &&
  94. ($cellColumnIndex < $this->beforeColumn)
  95. ) {
  96. return true;
  97. }
  98. return false;
  99. }
  100. }