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