See Release Notes
Long Term Support Release
1 <?php 2 3 namespace PhpOffice\PhpSpreadsheet\Cell; 4 5 use PhpOffice\PhpSpreadsheet\Exception; 6 use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; 7 8 class CellRange implements AddressRange 9 { 10 /** 11 * @var CellAddress 12 */ 13 protected $from; 14 15 /** 16 * @var CellAddress 17 */ 18 protected $to; 19 20 public function __construct(CellAddress $from, CellAddress $to) 21 { 22 $this->validateFromTo($from, $to); 23 } 24 25 private function validateFromTo(CellAddress $from, CellAddress $to): void 26 { 27 // Identify actual top-left and bottom-right values (in case we've been given top-right and bottom-left) 28 $firstColumn = min($from->columnId(), $to->columnId()); 29 $firstRow = min($from->rowId(), $to->rowId()); 30 $lastColumn = max($from->columnId(), $to->columnId()); 31 $lastRow = max($from->rowId(), $to->rowId()); 32 33 $fromWorksheet = $from->worksheet(); 34 $toWorksheet = $to->worksheet(); 35 $this->validateWorksheets($fromWorksheet, $toWorksheet); 36 37 $this->from = $this->cellAddressWrapper($firstColumn, $firstRow, $fromWorksheet); 38 $this->to = $this->cellAddressWrapper($lastColumn, $lastRow, $toWorksheet); 39 } 40 41 private function validateWorksheets(?Worksheet $fromWorksheet, ?Worksheet $toWorksheet): void 42 { 43 if ($fromWorksheet !== null && $toWorksheet !== null) { 44 // We could simply compare worksheets rather than worksheet titles; but at some point we may introduce 45 // support for 3d ranges; and at that point we drop this check and let the validation fall through 46 // to the check for same workbook; but unless we check on titles, this test will also detect if the 47 // worksheets are in different spreadsheets, and the next check will never execute or throw its 48 // own exception. 49 if ($fromWorksheet->getTitle() !== $toWorksheet->getTitle()) { 50 throw new Exception('3d Cell Ranges are not supported'); 51 } elseif ($fromWorksheet->getParent() !== $toWorksheet->getParent()) { 52 throw new Exception('Worksheets must be in the same spreadsheet'); 53 } 54 } 55 } 56 57 private function cellAddressWrapper(int $column, int $row, ?Worksheet $worksheet = null): CellAddress 58 { 59 $cellAddress = Coordinate::stringFromColumnIndex($column) . (string) $row; 60 61 return new class ($cellAddress, $worksheet) extends CellAddress { 62 public function nextRow(int $offset = 1): CellAddress 63 { 64 /** @var CellAddress $result */ 65 $result = parent::nextRow($offset); 66 $this->rowId = $result->rowId; 67 $this->cellAddress = $result->cellAddress; 68 69 return $this; 70 } 71 72 public function previousRow(int $offset = 1): CellAddress 73 { 74 /** @var CellAddress $result */ 75 $result = parent::previousRow($offset); 76 $this->rowId = $result->rowId; 77 $this->cellAddress = $result->cellAddress; 78 79 return $this; 80 } 81 82 public function nextColumn(int $offset = 1): CellAddress 83 { 84 /** @var CellAddress $result */ 85 $result = parent::nextColumn($offset); 86 $this->columnId = $result->columnId; 87 $this->columnName = $result->columnName; 88 $this->cellAddress = $result->cellAddress; 89 90 return $this; 91 } 92 93 public function previousColumn(int $offset = 1): CellAddress 94 { 95 /** @var CellAddress $result */ 96 $result = parent::previousColumn($offset); 97 $this->columnId = $result->columnId; 98 $this->columnName = $result->columnName; 99 $this->cellAddress = $result->cellAddress; 100 101 return $this; 102 } 103 }; 104 } 105 106 public function from(): CellAddress 107 { 108 // Re-order from/to in case the cell addresses have been modified 109 $this->validateFromTo($this->from, $this->to); 110 111 return $this->from; 112 } 113 114 public function to(): CellAddress 115 { 116 // Re-order from/to in case the cell addresses have been modified 117 $this->validateFromTo($this->from, $this->to); 118 119 return $this->to; 120 } 121 122 public function __toString(): string 123 { 124 // Re-order from/to in case the cell addresses have been modified 125 $this->validateFromTo($this->from, $this->to); 126 127 if ($this->from->cellAddress() === $this->to->cellAddress()) { 128 return "{$this->from->fullCellAddress()}"; 129 } 130 131 $fromAddress = $this->from->fullCellAddress(); 132 $toAddress = $this->to->cellAddress(); 133 134 return "{$fromAddress}:{$toAddress}"; 135 } 136 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body