Consistent `stringFromColumnIndex()` and `columnIndexFromString()`

Column indexes are always based on 1 everywhere in PhpSpreadsheet.
This is consistent with rows starting at 1, as well as Excel
function `COLUMN()`. It should also make it easier to reason about
columns and rows and remove any doubts whether a specific method is
expecting 0 based or 1 based indexes.

Fixes #273
Fixes https://github.com/PHPOffice/PHPExcel/issues/307
Fixes https://github.com/PHPOffice/PHPExcel/issues/476
This commit is contained in:
Adrien Crivelli 2017-11-25 19:26:41 +09:00
parent e0150fd43e
commit 8d76020590
No known key found for this signature in database
GPG Key ID: B182FD79DC6DE92E
32 changed files with 431 additions and 358 deletions

View File

@ -29,6 +29,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
### BREAKING CHANGE
- Extracted coordinate method to dedicate class [migration guide](./docs/topics/migration-from-PHPExcel.md).
- Column indexes are based on 1, see the [migration guide](./docs/topics/migration-from-PHPExcel.md).
- Standardization of array keys used for style, see the [migration guide](./docs/topics/migration-from-PHPExcel.md).
- Easier usage of PDF writers, and other custom readers and writers, see the [migration guide](./docs/topics/migration-from-PHPExcel.md).
- Easier usage of chart renderers, see the [migration guide](./docs/topics/migration-from-PHPExcel.md).

View File

@ -261,8 +261,7 @@ the cell's `getFormattedValue()` method.
``` php
// Get the value fom cell A6
$cellValue = $spreadsheet->getActiveSheet()->getCell('A6')
->getFormattedValue();
$cellValue = $spreadsheet->getActiveSheet()->getCell('A6')->getFormattedValue();
```
## Setting a cell value by column and row
@ -281,13 +280,12 @@ than from `1`.
## Retrieving a cell value by column and row
To retrieve the value of a cell, the cell should first be retrieved from
the worksheet using the getCellByColumnAndRow method. A cells value can
the worksheet using the `getCellByColumnAndRow()` method. A cells value can
be read again using the following line of code:
``` php
// Get the value fom cell B5
$cellValue = $spreadsheet->getActiveSheet()->getCellByColumnAndRow(1, 5)
->getValue();
$cellValue = $spreadsheet->getActiveSheet()->getCellByColumnAndRow(2, 5)->getValue();
```
If you need the calculated value of a cell, use the following code. This
@ -295,8 +293,7 @@ is further explained in .
``` php
// Get the value fom cell A4
$cellValue = $spreadsheet->getActiveSheet()->getCellByColumnAndRow(0, 4)
->getCalculatedValue();
$cellValue = $spreadsheet->getActiveSheet()->getCellByColumnAndRow(1, 4)->getCalculatedValue();
```
## Retrieving a range of cell values to an array
@ -374,8 +371,7 @@ One can use the possibility to access cell values by column and row
index like (0,1) instead of 'A1' for reading and writing cell values in
loops.
Note: In PhpSpreadsheet column index is 0-based while row index is
1-based. That means 'A1' \~ (0,1)
Note: In PhpSpreadsheet column index and row index are 1-based. That means `'A1'` ~ `[1, 1]`
Below is an example where we read all the values in a worksheet and
display them in a table.
@ -394,11 +390,9 @@ $highestColumnIndex = \PhpOffice\PhpSpreadsheet\Cell\Cell::columnIndexFromString
echo '<table>' . "\n";
for ($row = 1; $row <= $highestRow; ++$row) {
echo '<tr>' . PHP_EOL;
for ($col = 0; $col <= $highestColumnIndex; ++$col) {
echo '<td>' .
$worksheet->getCellByColumnAndRow($col, $row)
->getValue() .
'</td>' . PHP_EOL;
for ($col = 1; $col <= $highestColumnIndex; ++$col) {
$value = $worksheet->getCellByColumnAndRow($col, $row)->getValue();
echo '<td>' . $value . '</td>' . PHP_EOL;
}
echo '</tr>' . PHP_EOL;
}

View File

@ -363,3 +363,66 @@ $style = [
],
];
```
### Dedicated class to manipulate coordinates
Methods to manipulate coordinates that used to exists in `PHPExcel_Cell` were extracted
to a dedicated new class `\PhpOffice\PhpSpreadsheet\Cell\Coordinate`. The methods are:
- `absoluteCoordinate()`
- `absoluteReference()`
- `buildRange()`
- `columnIndexFromString()`
- `coordinateFromString()`
- `extractAllCellReferencesInRange()`
- `getRangeBoundaries()`
- `mergeRangesInCollection()`
- `rangeBoundaries()`
- `rangeDimension()`
- `splitRange()`
- `stringFromColumnIndex()`
### Column index based on 1
Column indexes are now based on 1. So column `A` is the index `1`. This is consistent
with rows starting at 1 and Excel function `COLUMN()` that returns `1` for column `A`.
So the code must be adapted with something like:
```php
// Before
$cell = $worksheet->getCellByColumnAndRow($column, $row);
for ($column = 0; $column < $max; $column++) {
$worksheet->setCellValueByColumnAndRow($column, $row, 'value ' . $column);
}
// After
$cell = $worksheet->getCellByColumnAndRow($column + 1, $row);
for ($column = 1; $column <= $max; $column++) {
$worksheet->setCellValueByColumnAndRow($column, $row, 'value ' . $column);
}
```
All the following methods are affected:
- `PHPExcel_Worksheet::cellExistsByColumnAndRow()`
- `PHPExcel_Worksheet::freezePaneByColumnAndRow()`
- `PHPExcel_Worksheet::getCellByColumnAndRow()`
- `PHPExcel_Worksheet::getColumnDimensionByColumn()`
- `PHPExcel_Worksheet::getCommentByColumnAndRow()`
- `PHPExcel_Worksheet::getStyleByColumnAndRow()`
- `PHPExcel_Worksheet::insertNewColumnBeforeByIndex()`
- `PHPExcel_Worksheet::mergeCellsByColumnAndRow()`
- `PHPExcel_Worksheet::protectCellsByColumnAndRow()`
- `PHPExcel_Worksheet::removeColumnByIndex()`
- `PHPExcel_Worksheet::setAutoFilterByColumnAndRow()`
- `PHPExcel_Worksheet::setBreakByColumnAndRow()`
- `PHPExcel_Worksheet::setCellValueByColumnAndRow()`
- `PHPExcel_Worksheet::setCellValueExplicitByColumnAndRow()`
- `PHPExcel_Worksheet::setSelectedCellByColumnAndRow()`
- `PHPExcel_Worksheet::stringFromColumnIndex()`
- `PHPExcel_Worksheet::unmergeCellsByColumnAndRow()`
- `PHPExcel_Worksheet::unprotectCellsByColumnAndRow()`
- `PHPExcel_Worksheet_PageSetup::addPrintAreaByColumnAndRow()`
- `PHPExcel_Worksheet_PageSetup::setPrintAreaByColumnAndRow()`

View File

@ -20,7 +20,7 @@ for ($i = 0; $i < 10; ++$i) {
$helper->log('Add data (begin)');
$t = microtime(true);
for ($col = 0; $col < 50; ++$col) {
for ($col = 1; $col <= 50; ++$col) {
for ($row = 0; $row < 100; ++$row) {
$str = ($row + $col);
$style = $styles[$row % 10];

View File

@ -3496,7 +3496,7 @@ class Calculation
$oCol[] = Coordinate::columnIndexFromString($oCR[0]) - 1;
$oRow[] = $oCR[1];
}
$cellRef = Coordinate::stringFromColumnIndex(min($oCol)) . min($oRow) . ':' . Coordinate::stringFromColumnIndex(max($oCol)) . max($oRow);
$cellRef = Coordinate::stringFromColumnIndex(min($oCol) + 1) . min($oRow) . ':' . Coordinate::stringFromColumnIndex(max($oCol) + 1) . max($oRow);
if ($pCellParent !== null) {
$cellValue = $this->extractCellRange($cellRef, $this->spreadsheet->getSheetByName($sheet1), false);
} else {
@ -3569,7 +3569,7 @@ class Calculation
$cellIntersect[$row] = array_intersect_key($operand1[$row], $operand2[$row]);
}
}
$cellRef = Coordinate::stringFromColumnIndex(min($oCol)) . min($oRow) . ':' . Coordinate::stringFromColumnIndex(max($oCol)) . max($oRow);
$cellRef = Coordinate::stringFromColumnIndex(min($oCol) + 1) . min($oRow) . ':' . Coordinate::stringFromColumnIndex(max($oCol) + 1) . max($oRow);
$this->debugLog->writeDebugLog('Evaluation Result is ', $this->showTypeDetails($cellIntersect));
$stack->push('Value', $cellIntersect, $cellRef);

View File

@ -53,7 +53,7 @@ class LookupRef
}
if ((!is_bool($referenceStyle)) || $referenceStyle) {
$rowRelative = $columnRelative = '$';
$column = Coordinate::stringFromColumnIndex($column - 1);
$column = Coordinate::stringFromColumnIndex($column);
if (($relativity == 2) || ($relativity == 4)) {
$columnRelative = '';
}
@ -399,7 +399,7 @@ class LookupRef
} else {
$endCellColumn += $columns;
}
$startCellColumn = Coordinate::stringFromColumnIndex($startCellColumn);
$startCellColumn = Coordinate::stringFromColumnIndex($startCellColumn + 1);
if (($height != null) && (!is_object($height))) {
$endCellRow = $startCellRow + $height - 1;
@ -410,7 +410,7 @@ class LookupRef
if (($endCellRow <= 0) || ($endCellColumn < 0)) {
return Functions::REF();
}
$endCellColumn = Coordinate::stringFromColumnIndex($endCellColumn);
$endCellColumn = Coordinate::stringFromColumnIndex($endCellColumn + 1);
$cellAddress = $startCellColumn . $startCellRow;
if (($startCellColumn != $endCellColumn) || ($startCellRow != $endCellRow)) {

View File

@ -4,6 +4,12 @@ namespace PhpOffice\PhpSpreadsheet\Cell;
use PhpOffice\PhpSpreadsheet\Exception;
/**
* Helper class to manipulate cell coordinates.
*
* Columns indexes and rows are always based on 1, **not** on 0. This match the behavior
* that Excel users are used to, and also match the Excel functions `COLUMN()` and `ROW()`.
*/
abstract class Coordinate
{
/**
@ -240,7 +246,7 @@ abstract class Coordinate
*
* @param string $pString eg 'A'
*
* @return int Column index (base 1 !!!)
* @return int Column index (A = 1)
*/
public static function columnIndexFromString($pString)
{
@ -284,9 +290,9 @@ abstract class Coordinate
}
/**
* String from columnindex.
* String from column index.
*
* @param int $columnIndex Column index (A = 0)
* @param int $columnIndex Column index (A = 1)
*
* @return string
*/
@ -295,7 +301,7 @@ abstract class Coordinate
static $indexCache = [];
if (!isset($indexCache[$columnIndex])) {
$indexValue = $columnIndex + 1;
$indexValue = $columnIndex;
$base26 = null;
do {
$characterValue = ($indexValue % 26) ?: 26;

View File

@ -248,7 +248,7 @@ class Cells
$columnList[] = Coordinate::columnIndexFromString($c);
}
return Coordinate::stringFromColumnIndex(max($columnList) - 1);
return Coordinate::stringFromColumnIndex(max($columnList) + 1);
}
/**

View File

@ -251,7 +251,7 @@ class Csv extends BaseReader
$worksheetInfo[0]['lastColumnIndex'] = max($worksheetInfo[0]['lastColumnIndex'], count($rowData) - 1);
}
$worksheetInfo[0]['lastColumnLetter'] = Coordinate::stringFromColumnIndex($worksheetInfo[0]['lastColumnIndex']);
$worksheetInfo[0]['lastColumnLetter'] = Coordinate::stringFromColumnIndex($worksheetInfo[0]['lastColumnIndex'] + 1);
$worksheetInfo[0]['totalColumns'] = $worksheetInfo[0]['lastColumnIndex'] + 1;
// Close file

View File

@ -138,7 +138,7 @@ class Gnumeric extends BaseReader
break;
}
}
$tmpInfo['lastColumnLetter'] = Coordinate::stringFromColumnIndex($tmpInfo['lastColumnIndex']);
$tmpInfo['lastColumnLetter'] = Coordinate::stringFromColumnIndex($tmpInfo['lastColumnIndex'] + 1);
$worksheetInfo[] = $tmpInfo;
}
}
@ -394,7 +394,7 @@ class Gnumeric extends BaseReader
$maxCol = $column;
}
$column = Coordinate::stringFromColumnIndex($column);
$column = Coordinate::stringFromColumnIndex($column + 1);
// Read cell?
if ($this->getReadFilter() !== null) {
@ -472,11 +472,11 @@ class Gnumeric extends BaseReader
$styleAttributes = $styleRegion->attributes();
if (($styleAttributes['startRow'] <= $maxRow) &&
($styleAttributes['startCol'] <= $maxCol)) {
$startColumn = Coordinate::stringFromColumnIndex((int) $styleAttributes['startCol']);
$startColumn = Coordinate::stringFromColumnIndex((int) $styleAttributes['startCol'] + 1);
$startRow = $styleAttributes['startRow'] + 1;
$endColumn = ($styleAttributes['endCol'] > $maxCol) ? $maxCol : (int) $styleAttributes['endCol'];
$endColumn = Coordinate::stringFromColumnIndex($endColumn);
$endColumn = Coordinate::stringFromColumnIndex($endColumn + 1);
$endRow = ($styleAttributes['endRow'] > $maxRow) ? $maxRow : $styleAttributes['endRow'];
$endRow += 1;
$cellRange = $startColumn . $startRow . ':' . $endColumn . $endRow;
@ -718,19 +718,19 @@ class Gnumeric extends BaseReader
$hidden = ((isset($columnAttributes['Hidden'])) && ($columnAttributes['Hidden'] == '1')) ? true : false;
$columnCount = (isset($columnAttributes['Count'])) ? $columnAttributes['Count'] : 1;
while ($c < $column) {
$spreadsheet->getActiveSheet()->getColumnDimension(Coordinate::stringFromColumnIndex($c))->setWidth($defaultWidth);
$spreadsheet->getActiveSheet()->getColumnDimension(Coordinate::stringFromColumnIndex($c + 1))->setWidth($defaultWidth);
++$c;
}
while (($c < ($column + $columnCount)) && ($c <= $maxCol)) {
$spreadsheet->getActiveSheet()->getColumnDimension(Coordinate::stringFromColumnIndex($c))->setWidth($columnWidth);
$spreadsheet->getActiveSheet()->getColumnDimension(Coordinate::stringFromColumnIndex($c + 1))->setWidth($columnWidth);
if ($hidden) {
$spreadsheet->getActiveSheet()->getColumnDimension(Coordinate::stringFromColumnIndex($c))->setVisible(false);
$spreadsheet->getActiveSheet()->getColumnDimension(Coordinate::stringFromColumnIndex($c + 1))->setVisible(false);
}
++$c;
}
}
while ($c <= $maxCol) {
$spreadsheet->getActiveSheet()->getColumnDimension(Coordinate::stringFromColumnIndex($c))->setWidth($defaultWidth);
$spreadsheet->getActiveSheet()->getColumnDimension(Coordinate::stringFromColumnIndex($c + 1))->setWidth($defaultWidth);
++$c;
}
}

View File

@ -215,7 +215,7 @@ class Ods extends BaseReader
$tmpInfo['totalColumns'] = max($tmpInfo['totalColumns'], $currCells);
$tmpInfo['lastColumnIndex'] = $tmpInfo['totalColumns'] - 1;
$tmpInfo['lastColumnLetter'] = Coordinate::stringFromColumnIndex($tmpInfo['lastColumnIndex']);
$tmpInfo['lastColumnLetter'] = Coordinate::stringFromColumnIndex($tmpInfo['lastColumnIndex'] + 1);
$worksheetInfo[] = $tmpInfo;
}
}
@ -707,7 +707,7 @@ class Ods extends BaseReader
$columnIndex += (int) $cellData->getAttributeNS($tableNs, 'number-columns-spanned');
$columnIndex -= 2;
$columnTo = Coordinate::stringFromColumnIndex($columnIndex);
$columnTo = Coordinate::stringFromColumnIndex($columnIndex + 1);
}
$rowTo = $rowID;

View File

@ -161,7 +161,7 @@ class Slk extends BaseReader
}
}
$worksheetInfo[0]['lastColumnLetter'] = Coordinate::stringFromColumnIndex($worksheetInfo[0]['lastColumnIndex']);
$worksheetInfo[0]['lastColumnLetter'] = Coordinate::stringFromColumnIndex($worksheetInfo[0]['lastColumnIndex'] + 1);
$worksheetInfo[0]['totalColumns'] = $worksheetInfo[0]['lastColumnIndex'] + 1;
// Close file
@ -337,7 +337,7 @@ class Slk extends BaseReader
if ($columnReference[0] == '[') {
$columnReference = $column + trim($columnReference, '[]');
}
$A1CellReference = Coordinate::stringFromColumnIndex($columnReference - 1) . $rowReference;
$A1CellReference = Coordinate::stringFromColumnIndex($columnReference) . $rowReference;
$value = substr_replace($value, $A1CellReference, $cellReference[0][1], strlen($cellReference[0][0]));
}
@ -351,7 +351,7 @@ class Slk extends BaseReader
break;
}
}
$columnLetter = Coordinate::stringFromColumnIndex($column - 1);
$columnLetter = Coordinate::stringFromColumnIndex($column);
$cellData = Calculation::unwrapResult($cellData);
// Set cell value
@ -419,22 +419,22 @@ class Slk extends BaseReader
}
}
if (($formatStyle > '') && ($column > '') && ($row > '')) {
$columnLetter = Coordinate::stringFromColumnIndex($column - 1);
$columnLetter = Coordinate::stringFromColumnIndex($column);
if (isset($this->formats[$formatStyle])) {
$spreadsheet->getActiveSheet()->getStyle($columnLetter . $row)->applyFromArray($this->formats[$formatStyle]);
}
}
if ((!empty($styleData)) && ($column > '') && ($row > '')) {
$columnLetter = Coordinate::stringFromColumnIndex($column - 1);
$columnLetter = Coordinate::stringFromColumnIndex($column);
$spreadsheet->getActiveSheet()->getStyle($columnLetter . $row)->applyFromArray($styleData);
}
if ($columnWidth > '') {
if ($startCol == $endCol) {
$startCol = Coordinate::stringFromColumnIndex($startCol - 1);
$startCol = Coordinate::stringFromColumnIndex($startCol);
$spreadsheet->getActiveSheet()->getColumnDimension($startCol)->setWidth($columnWidth);
} else {
$startCol = Coordinate::stringFromColumnIndex($startCol - 1);
$endCol = Coordinate::stringFromColumnIndex($endCol - 1);
$startCol = Coordinate::stringFromColumnIndex($startCol);
$endCol = Coordinate::stringFromColumnIndex($endCol);
$spreadsheet->getActiveSheet()->getColumnDimension($startCol)->setWidth($columnWidth);
do {
$spreadsheet->getActiveSheet()->getColumnDimension(++$startCol)->setWidth($columnWidth);

View File

@ -602,7 +602,7 @@ class Xls extends BaseReader
}
}
$tmpInfo['lastColumnLetter'] = Coordinate::stringFromColumnIndex($tmpInfo['lastColumnIndex']);
$tmpInfo['lastColumnLetter'] = Coordinate::stringFromColumnIndex($tmpInfo['lastColumnIndex'] + 1);
$tmpInfo['totalColumns'] = $tmpInfo['lastColumnIndex'] + 1;
$worksheetInfo[] = $tmpInfo;
@ -3222,7 +3222,7 @@ class Xls extends BaseReader
$cl = self::getUInt2d($recordData, 2 + 6 * $i + 4);
// not sure why two column indexes are necessary?
$this->phpSheet->setBreakByColumnAndRow($cf, $r, Worksheet::BREAK_ROW);
$this->phpSheet->setBreakByColumnAndRow($cf + 1, $r, Worksheet::BREAK_ROW);
}
}
}
@ -3249,7 +3249,7 @@ class Xls extends BaseReader
$rl = self::getUInt2d($recordData, 2 + 6 * $i + 4);
// not sure why two row indexes are necessary?
$this->phpSheet->setBreakByColumnAndRow($c, $rf, Worksheet::BREAK_COLUMN);
$this->phpSheet->setBreakByColumnAndRow($c + 1, $rf, Worksheet::BREAK_COLUMN);
}
}
}
@ -3593,10 +3593,10 @@ class Xls extends BaseReader
if (!$this->readDataOnly) {
// offset: 0; size: 2; index to first column in range
$fc = self::getUInt2d($recordData, 0); // first column index
$firstColumnIndex = self::getUInt2d($recordData, 0);
// offset: 2; size: 2; index to last column in range
$lc = self::getUInt2d($recordData, 2); // first column index
$lastColumnIndex = self::getUInt2d($recordData, 2);
// offset: 4; size: 2; width of the column in 1/256 of the width of the zero character
$width = self::getUInt2d($recordData, 4);
@ -3616,8 +3616,8 @@ class Xls extends BaseReader
// offset: 10; size: 2; not used
for ($i = $fc; $i <= $lc; ++$i) {
if ($lc == 255 || $lc == 256) {
for ($i = $firstColumnIndex + 1; $i <= $lastColumnIndex + 1; ++$i) {
if ($lastColumnIndex == 255 || $lastColumnIndex == 256) {
$this->phpSheet->getDefaultColumnDimension()->setWidth($width / 256);
break;
@ -3723,7 +3723,7 @@ class Xls extends BaseReader
// offset: 2; size: 2; index to column
$column = self::getUInt2d($recordData, 2);
$columnString = Coordinate::stringFromColumnIndex($column);
$columnString = Coordinate::stringFromColumnIndex($column + 1);
// Read cell?
if (($this->getReadFilter() !== null) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->phpSheet->getTitle())) {
@ -3767,7 +3767,7 @@ class Xls extends BaseReader
// offset: 2; size: 2; index to column
$column = self::getUInt2d($recordData, 2);
$columnString = Coordinate::stringFromColumnIndex($column);
$columnString = Coordinate::stringFromColumnIndex($column + 1);
$emptyCell = true;
// Read cell?
@ -3859,7 +3859,7 @@ class Xls extends BaseReader
// offset within record data
$offset = 4;
for ($i = 0; $i < $columns; ++$i) {
for ($i = 1; $i <= $columns; ++$i) {
$columnString = Coordinate::stringFromColumnIndex($colFirst + $i);
// Read cell?
@ -3904,7 +3904,7 @@ class Xls extends BaseReader
// offset: 2; size 2; index to column
$column = self::getUInt2d($recordData, 2);
$columnString = Coordinate::stringFromColumnIndex($column);
$columnString = Coordinate::stringFromColumnIndex($column + 1);
// Read cell?
if (($this->getReadFilter() !== null) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->phpSheet->getTitle())) {
@ -3945,7 +3945,7 @@ class Xls extends BaseReader
// offset: 2; size: 2; col index
$column = self::getUInt2d($recordData, 2);
$columnString = Coordinate::stringFromColumnIndex($column);
$columnString = Coordinate::stringFromColumnIndex($column + 1);
// offset: 20: size: variable; formula structure
$formulaStructure = substr($recordData, 20);
@ -3969,7 +3969,7 @@ class Xls extends BaseReader
// get the base cell, grab tExp token
$baseRow = self::getUInt2d($formulaStructure, 3);
$baseCol = self::getUInt2d($formulaStructure, 5);
$this->baseCell = Coordinate::stringFromColumnIndex($baseCol) . ($baseRow + 1);
$this->baseCell = Coordinate::stringFromColumnIndex($baseCol + 1) . ($baseRow + 1);
}
// Read cell?
@ -4129,7 +4129,7 @@ class Xls extends BaseReader
// offset: 2; size: 2; column index
$column = self::getUInt2d($recordData, 2);
$columnString = Coordinate::stringFromColumnIndex($column);
$columnString = Coordinate::stringFromColumnIndex($column + 1);
// Read cell?
if (($this->getReadFilter() !== null) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->phpSheet->getTitle())) {
@ -4193,7 +4193,7 @@ class Xls extends BaseReader
// add style information
if (!$this->readDataOnly && $this->readEmptyCells) {
for ($i = 0; $i < $length / 2 - 3; ++$i) {
$columnString = Coordinate::stringFromColumnIndex($fc + $i);
$columnString = Coordinate::stringFromColumnIndex($fc + $i + 1);
// Read cell?
if (($this->getReadFilter() !== null) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->phpSheet->getTitle())) {
@ -4229,7 +4229,7 @@ class Xls extends BaseReader
// offset: 2; size: 2; index to column
$column = self::getUInt2d($recordData, 2);
$columnString = Coordinate::stringFromColumnIndex($column);
$columnString = Coordinate::stringFromColumnIndex($column + 1);
// Read cell?
if (($this->getReadFilter() !== null) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->phpSheet->getTitle())) {
@ -4273,7 +4273,7 @@ class Xls extends BaseReader
// offset: 2; size: 2; col index
$col = self::getUInt2d($recordData, 2);
$columnString = Coordinate::stringFromColumnIndex($col);
$columnString = Coordinate::stringFromColumnIndex($col + 1);
// Read cell?
if (($this->getReadFilter() !== null) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->phpSheet->getTitle())) {
@ -4490,7 +4490,7 @@ class Xls extends BaseReader
if ($this->frozen) {
// frozen panes
$this->phpSheet->freezePane(Coordinate::stringFromColumnIndex($px) . ($py + 1));
$this->phpSheet->freezePane(Coordinate::stringFromColumnIndex($px + 1) . ($py + 1));
}
// unfrozen panes; split windows; not supported by PhpSpreadsheet core
}
@ -7103,7 +7103,7 @@ class Xls extends BaseReader
// offset: 2; size: 2; index to column or column offset + relative flags
// bit: 7-0; mask 0x00FF; column index
$column = Coordinate::stringFromColumnIndex(0x00FF & self::getUInt2d($cellAddressStructure, 2));
$column = Coordinate::stringFromColumnIndex((0x00FF & self::getUInt2d($cellAddressStructure, 2)) + 1);
// bit: 14; mask 0x4000; (1 = relative column index, 0 = absolute column index)
if (!(0x4000 & self::getUInt2d($cellAddressStructure, 2))) {
@ -7142,7 +7142,7 @@ class Xls extends BaseReader
// bit: 7-0; mask 0x00FF; column index
$colIndex = 0x00FF & self::getUInt2d($cellAddressStructure, 2);
$column = Coordinate::stringFromColumnIndex($colIndex);
$column = Coordinate::stringFromColumnIndex($colIndex + 1);
$column = '$' . $column;
} else {
// offset: 2; size: 2; index to column or column offset + relative flags
@ -7151,7 +7151,7 @@ class Xls extends BaseReader
$colIndex = $baseCol + $relativeColIndex;
$colIndex = ($colIndex < 256) ? $colIndex : $colIndex - 256;
$colIndex = ($colIndex >= 0) ? $colIndex : $colIndex + 256;
$column = Coordinate::stringFromColumnIndex($colIndex);
$column = Coordinate::stringFromColumnIndex($colIndex + 1);
}
// bit: 15; mask 0x8000; (1 = relative row index, 0 = absolute row index)
@ -7196,8 +7196,8 @@ class Xls extends BaseReader
}
// column index to letter
$fc = Coordinate::stringFromColumnIndex($fc);
$lc = Coordinate::stringFromColumnIndex($lc);
$fc = Coordinate::stringFromColumnIndex($fc + 1);
$lc = Coordinate::stringFromColumnIndex($lc + 1);
if ($fr == $lr and $fc == $lc) {
return "$fc$fr";
@ -7237,8 +7237,8 @@ class Xls extends BaseReader
}
// column index to letter
$fc = Coordinate::stringFromColumnIndex($fc);
$lc = Coordinate::stringFromColumnIndex($lc);
$fc = Coordinate::stringFromColumnIndex($fc + 1);
$lc = Coordinate::stringFromColumnIndex($lc + 1);
if ($fr == $lr and $fc == $lc) {
return "$fc$fr";
@ -7270,7 +7270,7 @@ class Xls extends BaseReader
// offset: 4; size: 2; index to first column or column offset + relative flags
// bit: 7-0; mask 0x00FF; column index
$fc = Coordinate::stringFromColumnIndex(0x00FF & self::getUInt2d($subData, 4));
$fc = Coordinate::stringFromColumnIndex((0x00FF & self::getUInt2d($subData, 4)) + 1);
// bit: 14; mask 0x4000; (1 = relative column index, 0 = absolute column index)
if (!(0x4000 & self::getUInt2d($subData, 4))) {
@ -7285,7 +7285,7 @@ class Xls extends BaseReader
// offset: 6; size: 2; index to last column or column offset + relative flags
// bit: 7-0; mask 0x00FF; column index
$lc = Coordinate::stringFromColumnIndex(0x00FF & self::getUInt2d($subData, 6));
$lc = Coordinate::stringFromColumnIndex((0x00FF & self::getUInt2d($subData, 6)) + 1);
// bit: 14; mask 0x4000; (1 = relative column index, 0 = absolute column index)
if (!(0x4000 & self::getUInt2d($subData, 6))) {
@ -7330,7 +7330,7 @@ class Xls extends BaseReader
// offset: 4; size: 2; first column with relative/absolute flags
// bit: 7-0; mask 0x00FF; column index
$fcIndex = 0x00FF & self::getUInt2d($subData, 4);
$fc = Coordinate::stringFromColumnIndex($fcIndex);
$fc = Coordinate::stringFromColumnIndex($fcIndex + 1);
$fc = '$' . $fc;
} else {
// column offset
@ -7340,7 +7340,7 @@ class Xls extends BaseReader
$fcIndex = $baseCol + $relativeFcIndex;
$fcIndex = ($fcIndex < 256) ? $fcIndex : $fcIndex - 256;
$fcIndex = ($fcIndex >= 0) ? $fcIndex : $fcIndex + 256;
$fc = Coordinate::stringFromColumnIndex($fcIndex);
$fc = Coordinate::stringFromColumnIndex($fcIndex + 1);
}
// bit: 15; mask 0x8000; (1 = relative row index, 0 = absolute row index)
@ -7360,7 +7360,7 @@ class Xls extends BaseReader
// offset: 6; size: 2; last column with relative/absolute flags
// bit: 7-0; mask 0x00FF; column index
$lcIndex = 0x00FF & self::getUInt2d($subData, 6);
$lc = Coordinate::stringFromColumnIndex($lcIndex);
$lc = Coordinate::stringFromColumnIndex($lcIndex + 1);
$lc = '$' . $lc;
} else {
// column offset
@ -7370,7 +7370,7 @@ class Xls extends BaseReader
$lcIndex = $baseCol + $relativeLcIndex;
$lcIndex = ($lcIndex < 256) ? $lcIndex : $lcIndex - 256;
$lcIndex = ($lcIndex >= 0) ? $lcIndex : $lcIndex + 256;
$lc = Coordinate::stringFromColumnIndex($lcIndex);
$lc = Coordinate::stringFromColumnIndex($lcIndex + 1);
}
// bit: 15; mask 0x8000; (1 = relative row index, 0 = absolute row index)

View File

@ -598,7 +598,7 @@ class Escher
$endOffsetY = Xls::getUInt2d($recordData, 16);
// set the start coordinates
$this->object->setStartCoordinates(Coordinate::stringFromColumnIndex($c1) . ($r1 + 1));
$this->object->setStartCoordinates(Coordinate::stringFromColumnIndex($c1 + 1) . ($r1 + 1));
// set the start offsetX
$this->object->setStartOffsetX($startOffsetX);
@ -607,7 +607,7 @@ class Escher
$this->object->setStartOffsetY($startOffsetY);
// set the end coordinates
$this->object->setEndCoordinates(Coordinate::stringFromColumnIndex($c2) . ($r2 + 1));
$this->object->setEndCoordinates(Coordinate::stringFromColumnIndex($c2 + 1) . ($r2 + 1));
// set the end offsetX
$this->object->setEndOffsetX($endOffsetX);

View File

@ -230,7 +230,7 @@ class Xlsx extends BaseReader
$xml->close();
$tmpInfo['lastColumnIndex'] = $tmpInfo['totalColumns'] - 1;
$tmpInfo['lastColumnLetter'] = Coordinate::stringFromColumnIndex($tmpInfo['lastColumnIndex']);
$tmpInfo['lastColumnLetter'] = Coordinate::stringFromColumnIndex($tmpInfo['lastColumnIndex'] + 1);
$worksheetInfo[] = $tmpInfo;
}
@ -734,7 +734,7 @@ class Xlsx extends BaseReader
$ySplit = 1 + (int) ($xmlSheet->sheetViews->sheetView->pane['ySplit']);
}
$docSheet->freezePaneByColumnAndRow($xSplit, $ySplit);
$docSheet->freezePaneByColumnAndRow($xSplit + 1, $ySplit);
}
}
@ -798,7 +798,7 @@ class Xlsx extends BaseReader
if (isset($xmlSheet->cols) && !$this->readDataOnly) {
foreach ($xmlSheet->cols->col as $col) {
for ($i = (int) ($col['min']) - 1; $i < (int) ($col['max']); ++$i) {
for ($i = (int) ($col['min']); $i <= (int) ($col['max']); ++$i) {
if ($col['style'] && !$this->readDataOnly) {
$docSheet->getColumnDimension(Coordinate::stringFromColumnIndex($i))->setXfIndex((int) ($col['style']));
}
@ -854,7 +854,7 @@ class Xlsx extends BaseReader
$docSheet->getRowDimension((int) ($row['r']))->setXfIndex((int) ($row['s']));
}
$rowIndex = 0; // Start form zero because Cell::stringFromColumnIndex start from A default, actually is 1
$rowIndex = 1;
foreach ($row->c as $c) {
$r = (string) $c['r'];
if ($r == '') {
@ -1214,7 +1214,7 @@ class Xlsx extends BaseReader
if ($xmlSheet && $xmlSheet->colBreaks && $xmlSheet->colBreaks->brk && !$this->readDataOnly) {
foreach ($xmlSheet->colBreaks->brk as $brk) {
if ($brk['man']) {
$docSheet->setBreak(Coordinate::stringFromColumnIndex((string) $brk['id']) . '1', Worksheet::BREAK_COLUMN);
$docSheet->setBreak(Coordinate::stringFromColumnIndex((string) $brk['id'] + 1) . '1', Worksheet::BREAK_COLUMN);
}
}
}
@ -1568,7 +1568,7 @@ class Xlsx extends BaseReader
)],
false
);
$objDrawing->setCoordinates(Coordinate::stringFromColumnIndex((string) $oneCellAnchor->from->col) . ($oneCellAnchor->from->row + 1));
$objDrawing->setCoordinates(Coordinate::stringFromColumnIndex(((string) $oneCellAnchor->from->col) + 1) . ($oneCellAnchor->from->row + 1));
$objDrawing->setOffsetX(Drawing::EMUToPixels($oneCellAnchor->from->colOff));
$objDrawing->setOffsetY(Drawing::EMUToPixels($oneCellAnchor->from->rowOff));
$objDrawing->setResizeProportional(false);
@ -1590,7 +1590,7 @@ class Xlsx extends BaseReader
$objDrawing->setWorksheet($docSheet);
} else {
// ? Can charts be positioned with a oneCellAnchor ?
$coordinates = Coordinate::stringFromColumnIndex((string) $oneCellAnchor->from->col) . ($oneCellAnchor->from->row + 1);
$coordinates = Coordinate::stringFromColumnIndex(((string) $oneCellAnchor->from->col) + 1) . ($oneCellAnchor->from->row + 1);
$offsetX = Drawing::EMUToPixels($oneCellAnchor->from->colOff);
$offsetY = Drawing::EMUToPixels($oneCellAnchor->from->rowOff);
$width = Drawing::EMUToPixels(self::getArrayItem($oneCellAnchor->ext->attributes(), 'cx'));
@ -1615,7 +1615,7 @@ class Xlsx extends BaseReader
)],
false
);
$objDrawing->setCoordinates(Coordinate::stringFromColumnIndex((string) $twoCellAnchor->from->col) . ($twoCellAnchor->from->row + 1));
$objDrawing->setCoordinates(Coordinate::stringFromColumnIndex(((string) $twoCellAnchor->from->col) + 1) . ($twoCellAnchor->from->row + 1));
$objDrawing->setOffsetX(Drawing::EMUToPixels($twoCellAnchor->from->colOff));
$objDrawing->setOffsetY(Drawing::EMUToPixels($twoCellAnchor->from->rowOff));
$objDrawing->setResizeProportional(false);
@ -1637,10 +1637,10 @@ class Xlsx extends BaseReader
}
$objDrawing->setWorksheet($docSheet);
} elseif (($this->includeCharts) && ($twoCellAnchor->graphicFrame)) {
$fromCoordinate = Coordinate::stringFromColumnIndex((string) $twoCellAnchor->from->col) . ($twoCellAnchor->from->row + 1);
$fromCoordinate = Coordinate::stringFromColumnIndex(((string) $twoCellAnchor->from->col) + 1) . ($twoCellAnchor->from->row + 1);
$fromOffsetX = Drawing::EMUToPixels($twoCellAnchor->from->colOff);
$fromOffsetY = Drawing::EMUToPixels($twoCellAnchor->from->rowOff);
$toCoordinate = Coordinate::stringFromColumnIndex((string) $twoCellAnchor->to->col) . ($twoCellAnchor->to->row + 1);
$toCoordinate = Coordinate::stringFromColumnIndex(((string) $twoCellAnchor->to->col) + 1) . ($twoCellAnchor->to->row + 1);
$toOffsetX = Drawing::EMUToPixels($twoCellAnchor->to->colOff);
$toOffsetY = Drawing::EMUToPixels($twoCellAnchor->to->rowOff);
$graphic = $twoCellAnchor->graphicFrame->children('http://schemas.openxmlformats.org/drawingml/2006/main')->graphic;

View File

@ -207,7 +207,7 @@ class Xml extends BaseReader
}
}
$tmpInfo['lastColumnLetter'] = Coordinate::stringFromColumnIndex($tmpInfo['lastColumnIndex']);
$tmpInfo['lastColumnLetter'] = Coordinate::stringFromColumnIndex($tmpInfo['lastColumnIndex'] + 1);
$tmpInfo['totalColumns'] = $tmpInfo['lastColumnIndex'] + 1;
$worksheetInfo[] = $tmpInfo;
@ -587,7 +587,7 @@ class Xml extends BaseReader
foreach ($worksheet->Table->Column as $columnData) {
$columnData_ss = $columnData->attributes($namespaces['ss']);
if (isset($columnData_ss['Index'])) {
$columnID = Coordinate::stringFromColumnIndex($columnData_ss['Index'] - 1);
$columnID = Coordinate::stringFromColumnIndex((int) $columnData_ss['Index']);
}
if (isset($columnData_ss['Width'])) {
$columnWidth = $columnData_ss['Width'];
@ -611,7 +611,7 @@ class Xml extends BaseReader
foreach ($rowData->Cell as $cell) {
$cell_ss = $cell->attributes($namespaces['ss']);
if (isset($cell_ss['Index'])) {
$columnID = Coordinate::stringFromColumnIndex($cell_ss['Index'] - 1);
$columnID = Coordinate::stringFromColumnIndex((int) $cell_ss['Index']);
}
$cellRange = $columnID . $rowID;
@ -631,7 +631,7 @@ class Xml extends BaseReader
$columnTo = $columnID;
if (isset($cell_ss['MergeAcross'])) {
$additionalMergedCells += (int) $cell_ss['MergeAcross'];
$columnTo = Coordinate::stringFromColumnIndex(Coordinate::columnIndexFromString($columnID) + $cell_ss['MergeAcross'] - 1);
$columnTo = Coordinate::stringFromColumnIndex(Coordinate::columnIndexFromString($columnID) + $cell_ss['MergeAcross']);
}
$rowTo = $rowID;
if (isset($cell_ss['MergeDown'])) {
@ -739,7 +739,7 @@ class Xml extends BaseReader
if ($columnReference[0] == '[') {
$columnReference = $columnNumber + trim($columnReference, '[]');
}
$A1CellReference = Coordinate::stringFromColumnIndex($columnReference - 1) . $rowReference;
$A1CellReference = Coordinate::stringFromColumnIndex($columnReference) . $rowReference;
$value = substr_replace($value, $A1CellReference, $cellReference[0][1], strlen($cellReference[0][0]));
}
}

View File

@ -372,8 +372,6 @@ class ReferenceHelper
$allCoordinates = $pSheet->getCoordinates();
// Get coordinate of $pBefore
$beforeColumn = 'A';
$beforeRow = 1;
list($beforeColumn, $beforeRow) = Coordinate::coordinateFromString($pBefore);
$beforeColumnIndex = Coordinate::columnIndexFromString($beforeColumn);
@ -385,7 +383,7 @@ class ReferenceHelper
if ($pNumCols < 0 && $beforeColumnIndex - 2 + $pNumCols > 0) {
for ($i = 1; $i <= $highestRow - 1; ++$i) {
for ($j = $beforeColumnIndex - 1 + $pNumCols; $j <= $beforeColumnIndex - 2; ++$j) {
$coordinate = Coordinate::stringFromColumnIndex($j) . $i;
$coordinate = Coordinate::stringFromColumnIndex($j + 1) . $i;
$pSheet->removeConditionalStyles($coordinate);
if ($pSheet->cellExists($coordinate)) {
$pSheet->getCell($coordinate)->setValueExplicit('', DataType::TYPE_NULL);
@ -399,7 +397,7 @@ class ReferenceHelper
if ($pNumRows < 0 && $beforeRow - 1 + $pNumRows > 0) {
for ($i = $beforeColumnIndex - 1; $i <= Coordinate::columnIndexFromString($highestColumn) - 1; ++$i) {
for ($j = $beforeRow + $pNumRows; $j <= $beforeRow - 1; ++$j) {
$coordinate = Coordinate::stringFromColumnIndex($i) . $j;
$coordinate = Coordinate::stringFromColumnIndex($i + 1) . $j;
$pSheet->removeConditionalStyles($coordinate);
if ($pSheet->cellExists($coordinate)) {
$pSheet->getCell($coordinate)->setValueExplicit('', DataType::TYPE_NULL);
@ -423,7 +421,7 @@ class ReferenceHelper
}
// New coordinate
$newCoordinate = Coordinate::stringFromColumnIndex($cellIndex - 1 + $pNumCols) . ($cell->getRow() + $pNumRows);
$newCoordinate = Coordinate::stringFromColumnIndex($cellIndex + $pNumCols) . ($cell->getRow() + $pNumRows);
// Should the cell be updated? Move value and cellXf index from one cell to another.
if (($cellIndex >= $beforeColumnIndex) && ($cell->getRow() >= $beforeRow)) {
@ -459,12 +457,12 @@ class ReferenceHelper
if ($pNumCols > 0 && $beforeColumnIndex - 2 > 0) {
for ($i = $beforeRow; $i <= $highestRow - 1; ++$i) {
// Style
$coordinate = Coordinate::stringFromColumnIndex($beforeColumnIndex - 2) . $i;
$coordinate = Coordinate::stringFromColumnIndex($beforeColumnIndex - 1) . $i;
if ($pSheet->cellExists($coordinate)) {
$xfIndex = $pSheet->getCell($coordinate)->getXfIndex();
$conditionalStyles = $pSheet->conditionalStylesExists($coordinate) ?
$pSheet->getConditionalStyles($coordinate) : false;
for ($j = $beforeColumnIndex - 1; $j <= $beforeColumnIndex - 2 + $pNumCols; ++$j) {
for ($j = $beforeColumnIndex; $j <= $beforeColumnIndex - 1 + $pNumCols; ++$j) {
$pSheet->getCellByColumnAndRow($j, $i)->setXfIndex($xfIndex);
if ($conditionalStyles) {
$cloned = [];
@ -479,7 +477,7 @@ class ReferenceHelper
}
if ($pNumRows > 0 && $beforeRow - 1 > 0) {
for ($i = $beforeColumnIndex - 1; $i <= Coordinate::columnIndexFromString($highestColumn) - 1; ++$i) {
for ($i = $beforeColumnIndex; $i <= Coordinate::columnIndexFromString($highestColumn); ++$i) {
// Style
$coordinate = Coordinate::stringFromColumnIndex($i) . ($beforeRow - 1);
if ($pSheet->cellExists($coordinate)) {
@ -541,8 +539,8 @@ class ReferenceHelper
$deleteColumn = $columnIndex + $pNumCols - 1;
$deleteCount = abs($pNumCols);
for ($i = 1; $i <= $deleteCount; ++$i) {
if (isset($autoFilterColumns[Coordinate::stringFromColumnIndex($deleteColumn)])) {
$autoFilter->clearColumn(Coordinate::stringFromColumnIndex($deleteColumn));
if (isset($autoFilterColumns[Coordinate::stringFromColumnIndex($deleteColumn + 1)])) {
$autoFilter->clearColumn(Coordinate::stringFromColumnIndex($deleteColumn + 1));
}
++$deleteColumn;
}
@ -551,25 +549,20 @@ class ReferenceHelper
// Shuffle columns in autofilter range
if ($pNumCols > 0) {
// For insert, we shuffle from end to beginning to avoid overwriting
$startColID = Coordinate::stringFromColumnIndex($startCol - 1);
$toColID = Coordinate::stringFromColumnIndex($startCol + $pNumCols - 1);
$endColID = Coordinate::stringFromColumnIndex($rangeEnd[0]);
$startColRef = $startCol;
$endColRef = $rangeEnd[0];
$toColRef = $rangeEnd[0] + $pNumCols;
do {
$autoFilter->shiftColumn(Coordinate::stringFromColumnIndex($endColRef - 1), Coordinate::stringFromColumnIndex($toColRef - 1));
$autoFilter->shiftColumn(Coordinate::stringFromColumnIndex($endColRef), Coordinate::stringFromColumnIndex($toColRef));
--$endColRef;
--$toColRef;
} while ($startColRef <= $endColRef);
} else {
// For delete, we shuffle from beginning to end to avoid overwriting
$startColID = Coordinate::stringFromColumnIndex($startCol - 1);
$toColID = Coordinate::stringFromColumnIndex($startCol + $pNumCols - 1);
$endColID = Coordinate::stringFromColumnIndex($rangeEnd[0]);
$startColID = Coordinate::stringFromColumnIndex($startCol);
$toColID = Coordinate::stringFromColumnIndex($startCol + $pNumCols);
$endColID = Coordinate::stringFromColumnIndex($rangeEnd[0] + 1);
do {
$autoFilter->shiftColumn($startColID, $toColID);
++$startColID;
@ -881,7 +874,7 @@ class ReferenceHelper
// Create new column reference
if ($updateColumn) {
$newColumn = Coordinate::stringFromColumnIndex(Coordinate::columnIndexFromString($newColumn) - 1 + $pNumCols);
$newColumn = Coordinate::stringFromColumnIndex(Coordinate::columnIndexFromString($newColumn) + $pNumCols);
}
// Create new row reference

View File

@ -111,8 +111,8 @@ class Xls
$distanceX = 0;
// add the widths of the spanning columns
$startColumnIndex = Coordinate::columnIndexFromString($startColumn) - 1; // 1-based
$endColumnIndex = Coordinate::columnIndexFromString($endColumn) - 1; // 1-based
$startColumnIndex = Coordinate::columnIndexFromString($startColumn);
$endColumnIndex = Coordinate::columnIndexFromString($endColumn);
for ($i = $startColumnIndex; $i <= $endColumnIndex; ++$i) {
$distanceX += self::sizeCol($sheet, Coordinate::stringFromColumnIndex($i));
}
@ -212,7 +212,7 @@ class Xls
public static function oneAnchor2twoAnchor($sheet, $coordinates, $offsetX, $offsetY, $width, $height)
{
list($column, $row) = Coordinate::coordinateFromString($coordinates);
$col_start = Coordinate::columnIndexFromString($column) - 1;
$col_start = Coordinate::columnIndexFromString($column);
$row_start = $row - 1;
$x1 = $offsetX;

View File

@ -210,8 +210,8 @@ class Style extends Supervisor
$rangeEnd = Coordinate::coordinateFromString($rangeB);
// Translate column into index
$rangeStart[0] = Coordinate::columnIndexFromString($rangeStart[0]) - 1;
$rangeEnd[0] = Coordinate::columnIndexFromString($rangeEnd[0]) - 1;
$rangeStart[0] = Coordinate::columnIndexFromString($rangeStart[0]);
$rangeEnd[0] = Coordinate::columnIndexFromString($rangeEnd[0]);
// Make sure we can loop upwards on rows and columns
if ($rangeStart[0] > $rangeEnd[0] && $rangeStart[1] > $rangeEnd[1]) {

View File

@ -202,7 +202,7 @@ class AutoFilter
public function getColumnByOffset($pColumnOffset)
{
list($rangeStart, $rangeEnd) = Coordinate::rangeBoundaries($this->range);
$pColumn = Coordinate::stringFromColumnIndex($rangeStart[0] + $pColumnOffset - 1);
$pColumn = Coordinate::stringFromColumnIndex($rangeStart[0] + $pColumnOffset);
return $this->getColumn($pColumn);
}

View File

@ -11,14 +11,7 @@ abstract class CellIterator implements \Iterator
*
* @var Worksheet
*/
protected $subject;
/**
* Current iterator position.
*
* @var mixed
*/
protected $position;
protected $worksheet;
/**
* Iterate only existing cells.
@ -32,7 +25,7 @@ abstract class CellIterator implements \Iterator
*/
public function __destruct()
{
unset($this->subject);
unset($this->worksheet);
}
/**

View File

@ -7,26 +7,33 @@ use PhpOffice\PhpSpreadsheet\Exception as PhpSpreadsheetException;
class ColumnCellIterator extends CellIterator
{
/**
* Current iterator position.
*
* @var int
*/
private $currentRow;
/**
* Column index.
*
* @var string
*/
protected $columnIndex;
private $columnIndex;
/**
* Start position.
*
* @var int
*/
protected $startRow = 1;
private $startRow = 1;
/**
* End position.
*
* @var int
*/
protected $endRow = 1;
private $endRow = 1;
/**
* Create a new row iterator.
@ -39,8 +46,8 @@ class ColumnCellIterator extends CellIterator
public function __construct(Worksheet $subject = null, $columnIndex = 'A', $startRow = 1, $endRow = null)
{
// Set subject
$this->subject = $subject;
$this->columnIndex = Coordinate::columnIndexFromString($columnIndex) - 1;
$this->worksheet = $subject;
$this->columnIndex = Coordinate::columnIndexFromString($columnIndex);
$this->resetEnd($endRow);
$this->resetStart($startRow);
}
@ -50,7 +57,7 @@ class ColumnCellIterator extends CellIterator
*/
public function __destruct()
{
unset($this->subject);
unset($this->worksheet);
}
/**
@ -82,7 +89,7 @@ class ColumnCellIterator extends CellIterator
*/
public function resetEnd($endRow = null)
{
$this->endRow = ($endRow) ? $endRow : $this->subject->getHighestRow();
$this->endRow = ($endRow) ? $endRow : $this->worksheet->getHighestRow();
$this->adjustForExistingOnlyRange();
return $this;
@ -101,10 +108,10 @@ class ColumnCellIterator extends CellIterator
{
if (($row < $this->startRow) || ($row > $this->endRow)) {
throw new PhpSpreadsheetException("Row $row is out of range ({$this->startRow} - {$this->endRow})");
} elseif ($this->onlyExistingCells && !($this->subject->cellExistsByColumnAndRow($this->columnIndex, $row))) {
} elseif ($this->onlyExistingCells && !($this->worksheet->cellExistsByColumnAndRow($this->columnIndex, $row))) {
throw new PhpSpreadsheetException('In "IterateOnlyExistingCells" mode and Cell does not exist');
}
$this->position = $row;
$this->currentRow = $row;
return $this;
}
@ -114,7 +121,7 @@ class ColumnCellIterator extends CellIterator
*/
public function rewind()
{
$this->position = $this->startRow;
$this->currentRow = $this->startRow;
}
/**
@ -124,7 +131,7 @@ class ColumnCellIterator extends CellIterator
*/
public function current()
{
return $this->subject->getCellByColumnAndRow($this->columnIndex, $this->position);
return $this->worksheet->getCellByColumnAndRow($this->columnIndex, $this->currentRow);
}
/**
@ -134,7 +141,7 @@ class ColumnCellIterator extends CellIterator
*/
public function key()
{
return $this->position;
return $this->currentRow;
}
/**
@ -143,10 +150,10 @@ class ColumnCellIterator extends CellIterator
public function next()
{
do {
++$this->position;
++$this->currentRow;
} while (($this->onlyExistingCells) &&
(!$this->subject->cellExistsByColumnAndRow($this->columnIndex, $this->position)) &&
($this->position <= $this->endRow));
(!$this->worksheet->cellExistsByColumnAndRow($this->columnIndex, $this->currentRow)) &&
($this->currentRow <= $this->endRow));
}
/**
@ -154,15 +161,15 @@ class ColumnCellIterator extends CellIterator
*/
public function prev()
{
if ($this->position <= $this->startRow) {
if ($this->currentRow <= $this->startRow) {
throw new PhpSpreadsheetException("Row is already at the beginning of range ({$this->startRow} - {$this->endRow})");
}
do {
--$this->position;
--$this->currentRow;
} while (($this->onlyExistingCells) &&
(!$this->subject->cellExistsByColumnAndRow($this->columnIndex, $this->position)) &&
($this->position >= $this->startRow));
(!$this->worksheet->cellExistsByColumnAndRow($this->columnIndex, $this->currentRow)) &&
($this->currentRow >= $this->startRow));
}
/**
@ -172,7 +179,7 @@ class ColumnCellIterator extends CellIterator
*/
public function valid()
{
return $this->position <= $this->endRow;
return $this->currentRow <= $this->endRow;
}
/**
@ -183,14 +190,14 @@ class ColumnCellIterator extends CellIterator
protected function adjustForExistingOnlyRange()
{
if ($this->onlyExistingCells) {
while ((!$this->subject->cellExistsByColumnAndRow($this->columnIndex, $this->startRow)) &&
while ((!$this->worksheet->cellExistsByColumnAndRow($this->columnIndex, $this->startRow)) &&
($this->startRow <= $this->endRow)) {
++$this->startRow;
}
if ($this->startRow > $this->endRow) {
throw new PhpSpreadsheetException('No cells exist within the specified range');
}
while ((!$this->subject->cellExistsByColumnAndRow($this->columnIndex, $this->endRow)) &&
while ((!$this->worksheet->cellExistsByColumnAndRow($this->columnIndex, $this->endRow)) &&
($this->endRow >= $this->startRow)) {
--$this->endRow;
}

View File

@ -13,40 +13,40 @@ class ColumnIterator implements \Iterator
*
* @var Worksheet
*/
private $subject;
private $worksheet;
/**
* Current iterator position.
*
* @var int
*/
private $position = 0;
private $currentColumnIndex = 1;
/**
* Start position.
*
* @var int
*/
private $startColumn = 0;
private $startColumnIndex = 1;
/**
* End position.
*
* @var int
*/
private $endColumn = 0;
private $endColumnIndex = 1;
/**
* Create a new column iterator.
*
* @param Worksheet $subject The worksheet to iterate over
* @param Worksheet $worksheet The worksheet to iterate over
* @param string $startColumn The column address at which to start iterating
* @param string $endColumn Optionally, the column address at which to stop iterating
*/
public function __construct(Worksheet $subject, $startColumn = 'A', $endColumn = null)
public function __construct(Worksheet $worksheet, $startColumn = 'A', $endColumn = null)
{
// Set subject
$this->subject = $subject;
$this->worksheet = $worksheet;
$this->resetEnd($endColumn);
$this->resetStart($startColumn);
}
@ -56,13 +56,13 @@ class ColumnIterator implements \Iterator
*/
public function __destruct()
{
unset($this->subject);
unset($this->worksheet);
}
/**
* (Re)Set the start column and the current column pointer.
*
* @param int $startColumn The column address at which to start iterating
* @param string $startColumn The column address at which to start iterating
*
* @throws Exception
*
@ -70,14 +70,14 @@ class ColumnIterator implements \Iterator
*/
public function resetStart($startColumn = 'A')
{
$startColumnIndex = Coordinate::columnIndexFromString($startColumn) - 1;
if ($startColumnIndex > Coordinate::columnIndexFromString($this->subject->getHighestColumn()) - 1) {
throw new Exception("Start column ({$startColumn}) is beyond highest column ({$this->subject->getHighestColumn()})");
$startColumnIndex = Coordinate::columnIndexFromString($startColumn);
if ($startColumnIndex > Coordinate::columnIndexFromString($this->worksheet->getHighestColumn())) {
throw new Exception("Start column ({$startColumn}) is beyond highest column ({$this->worksheet->getHighestColumn()})");
}
$this->startColumn = $startColumnIndex;
if ($this->endColumn < $this->startColumn) {
$this->endColumn = $this->startColumn;
$this->startColumnIndex = $startColumnIndex;
if ($this->endColumnIndex < $this->startColumnIndex) {
$this->endColumnIndex = $this->startColumnIndex;
}
$this->seek($startColumn);
@ -93,8 +93,8 @@ class ColumnIterator implements \Iterator
*/
public function resetEnd($endColumn = null)
{
$endColumn = ($endColumn) ? $endColumn : $this->subject->getHighestColumn();
$this->endColumn = Coordinate::columnIndexFromString($endColumn) - 1;
$endColumn = $endColumn ? $endColumn : $this->worksheet->getHighestColumn();
$this->endColumnIndex = Coordinate::columnIndexFromString($endColumn);
return $this;
}
@ -110,11 +110,11 @@ class ColumnIterator implements \Iterator
*/
public function seek($column = 'A')
{
$column = Coordinate::columnIndexFromString($column) - 1;
if (($column < $this->startColumn) || ($column > $this->endColumn)) {
throw new PhpSpreadsheetException("Column $column is out of range ({$this->startColumn} - {$this->endColumn})");
$column = Coordinate::columnIndexFromString($column);
if (($column < $this->startColumnIndex) || ($column > $this->endColumnIndex)) {
throw new PhpSpreadsheetException("Column $column is out of range ({$this->startColumnIndex} - {$this->endColumnIndex})");
}
$this->position = $column;
$this->currentColumnIndex = $column;
return $this;
}
@ -124,7 +124,7 @@ class ColumnIterator implements \Iterator
*/
public function rewind()
{
$this->position = $this->startColumn;
$this->currentColumnIndex = $this->startColumnIndex;
}
/**
@ -134,7 +134,7 @@ class ColumnIterator implements \Iterator
*/
public function current()
{
return new Column($this->subject, Coordinate::stringFromColumnIndex($this->position));
return new Column($this->worksheet, Coordinate::stringFromColumnIndex($this->currentColumnIndex));
}
/**
@ -144,7 +144,7 @@ class ColumnIterator implements \Iterator
*/
public function key()
{
return Coordinate::stringFromColumnIndex($this->position);
return Coordinate::stringFromColumnIndex($this->currentColumnIndex);
}
/**
@ -152,7 +152,7 @@ class ColumnIterator implements \Iterator
*/
public function next()
{
++$this->position;
++$this->currentColumnIndex;
}
/**
@ -162,10 +162,10 @@ class ColumnIterator implements \Iterator
*/
public function prev()
{
if ($this->position <= $this->startColumn) {
throw new PhpSpreadsheetException('Column is already at the beginning of range (' . Coordinate::stringFromColumnIndex($this->endColumn) . ' - ' . Coordinate::stringFromColumnIndex($this->endColumn) . ')');
if ($this->currentColumnIndex <= $this->startColumnIndex) {
throw new PhpSpreadsheetException('Column is already at the beginning of range (' . Coordinate::stringFromColumnIndex($this->endColumnIndex) . ' - ' . Coordinate::stringFromColumnIndex($this->endColumnIndex) . ')');
}
--$this->position;
--$this->currentColumnIndex;
}
/**
@ -175,6 +175,6 @@ class ColumnIterator implements \Iterator
*/
public function valid()
{
return $this->position <= $this->endColumn;
return $this->currentColumnIndex <= $this->endColumnIndex;
}
}

View File

@ -749,7 +749,7 @@ class PageSetup
* @param int $index Identifier for a specific print area range allowing several ranges to be set
* When the method is "O"verwrite, then a positive integer index will overwrite that indexed
* entry in the print areas list; a negative index value will identify which entry to
* overwrite working bacward through the print area to the list, with the last entry as -1.
* overwrite working backward through the print area to the list, with the last entry as -1.
* Specifying an index value of 0, will overwrite <b>all</b> existing print ranges.
* When the method is "I"nsert, then a positive index will insert after that indexed entry in
* the print areas list, while a negative index will insert before the indexed entry.

View File

@ -7,39 +7,46 @@ use PhpOffice\PhpSpreadsheet\Exception as PhpSpreadsheetException;
class RowCellIterator extends CellIterator
{
/**
* Current iterator position.
*
* @var int
*/
private $currentColumnIndex;
/**
* Row index.
*
* @var int
*/
protected $rowIndex;
private $rowIndex = 1;
/**
* Start position.
*
* @var int
*/
protected $startColumn = 0;
private $startColumnIndex = 1;
/**
* End position.
*
* @var int
*/
protected $endColumn = 0;
private $endColumnIndex = 1;
/**
* Create a new column iterator.
*
* @param Worksheet $subject The worksheet to iterate over
* @param Worksheet $worksheet The worksheet to iterate over
* @param int $rowIndex The row that we want to iterate
* @param string $startColumn The column address at which to start iterating
* @param string $endColumn Optionally, the column address at which to stop iterating
*/
public function __construct(Worksheet $subject = null, $rowIndex = 1, $startColumn = 'A', $endColumn = null)
public function __construct(Worksheet $worksheet = null, $rowIndex = 1, $startColumn = 'A', $endColumn = null)
{
// Set subject and row index
$this->subject = $subject;
$this->worksheet = $worksheet;
$this->rowIndex = $rowIndex;
$this->resetEnd($endColumn);
$this->resetStart($startColumn);
@ -50,13 +57,13 @@ class RowCellIterator extends CellIterator
*/
public function __destruct()
{
unset($this->subject);
unset($this->worksheet);
}
/**
* (Re)Set the start column and the current column pointer.
*
* @param int $startColumn The column address at which to start iterating
* @param string $startColumn The column address at which to start iterating
*
* @throws PhpSpreadsheetException
*
@ -64,10 +71,9 @@ class RowCellIterator extends CellIterator
*/
public function resetStart($startColumn = 'A')
{
$startColumnIndex = Coordinate::columnIndexFromString($startColumn) - 1;
$this->startColumn = $startColumnIndex;
$this->startColumnIndex = Coordinate::columnIndexFromString($startColumn);
$this->adjustForExistingOnlyRange();
$this->seek(Coordinate::stringFromColumnIndex($this->startColumn));
$this->seek(Coordinate::stringFromColumnIndex($this->startColumnIndex));
return $this;
}
@ -83,8 +89,8 @@ class RowCellIterator extends CellIterator
*/
public function resetEnd($endColumn = null)
{
$endColumn = ($endColumn) ? $endColumn : $this->subject->getHighestColumn();
$this->endColumn = Coordinate::columnIndexFromString($endColumn) - 1;
$endColumn = $endColumn ? $endColumn : $this->worksheet->getHighestColumn();
$this->endColumnIndex = Coordinate::columnIndexFromString($endColumn);
$this->adjustForExistingOnlyRange();
return $this;
@ -101,13 +107,13 @@ class RowCellIterator extends CellIterator
*/
public function seek($column = 'A')
{
$column = Coordinate::columnIndexFromString($column) - 1;
if (($column < $this->startColumn) || ($column > $this->endColumn)) {
throw new PhpSpreadsheetException("Column $column is out of range ({$this->startColumn} - {$this->endColumn})");
} elseif ($this->onlyExistingCells && !($this->subject->cellExistsByColumnAndRow($column, $this->rowIndex))) {
$column = Coordinate::columnIndexFromString($column);
if (($column < $this->startColumnIndex) || ($column > $this->endColumnIndex)) {
throw new PhpSpreadsheetException("Column $column is out of range ({$this->startColumnIndex} - {$this->endColumnIndex})");
} elseif ($this->onlyExistingCells && !($this->worksheet->cellExistsByColumnAndRow($column, $this->rowIndex))) {
throw new PhpSpreadsheetException('In "IterateOnlyExistingCells" mode and Cell does not exist');
}
$this->position = $column;
$this->currentColumnIndex = $column;
return $this;
}
@ -117,7 +123,7 @@ class RowCellIterator extends CellIterator
*/
public function rewind()
{
$this->position = $this->startColumn;
$this->currentColumnIndex = $this->startColumnIndex;
}
/**
@ -127,7 +133,7 @@ class RowCellIterator extends CellIterator
*/
public function current()
{
return $this->subject->getCellByColumnAndRow($this->position, $this->rowIndex);
return $this->worksheet->getCellByColumnAndRow($this->currentColumnIndex, $this->rowIndex);
}
/**
@ -137,7 +143,7 @@ class RowCellIterator extends CellIterator
*/
public function key()
{
return Coordinate::stringFromColumnIndex($this->position);
return Coordinate::stringFromColumnIndex($this->currentColumnIndex);
}
/**
@ -146,8 +152,8 @@ class RowCellIterator extends CellIterator
public function next()
{
do {
++$this->position;
} while (($this->onlyExistingCells) && (!$this->subject->cellExistsByColumnAndRow($this->position, $this->rowIndex)) && ($this->position <= $this->endColumn));
++$this->currentColumnIndex;
} while (($this->onlyExistingCells) && (!$this->worksheet->cellExistsByColumnAndRow($this->currentColumnIndex, $this->rowIndex)) && ($this->currentColumnIndex <= $this->endColumnIndex));
}
/**
@ -157,12 +163,12 @@ class RowCellIterator extends CellIterator
*/
public function prev()
{
if ($this->position <= $this->startColumn) {
throw new PhpSpreadsheetException('Column is already at the beginning of range (' . Coordinate::stringFromColumnIndex($this->endColumn) . ' - ' . Coordinate::stringFromColumnIndex($this->endColumn) . ')');
if ($this->currentColumnIndex <= $this->startColumnIndex) {
throw new PhpSpreadsheetException('Column is already at the beginning of range (' . Coordinate::stringFromColumnIndex($this->endColumnIndex) . ' - ' . Coordinate::stringFromColumnIndex($this->endColumnIndex) . ')');
}
do {
--$this->position;
} while (($this->onlyExistingCells) && (!$this->subject->cellExistsByColumnAndRow($this->position, $this->rowIndex)) && ($this->position >= $this->startColumn));
--$this->currentColumnIndex;
} while (($this->onlyExistingCells) && (!$this->worksheet->cellExistsByColumnAndRow($this->currentColumnIndex, $this->rowIndex)) && ($this->currentColumnIndex >= $this->startColumnIndex));
}
/**
@ -172,7 +178,7 @@ class RowCellIterator extends CellIterator
*/
public function valid()
{
return $this->position <= $this->endColumn;
return $this->currentColumnIndex <= $this->endColumnIndex;
}
/**
@ -183,16 +189,16 @@ class RowCellIterator extends CellIterator
protected function adjustForExistingOnlyRange()
{
if ($this->onlyExistingCells) {
while ((!$this->subject->cellExistsByColumnAndRow($this->startColumn, $this->rowIndex)) && ($this->startColumn <= $this->endColumn)) {
++$this->startColumn;
while ((!$this->worksheet->cellExistsByColumnAndRow($this->startColumnIndex, $this->rowIndex)) && ($this->startColumnIndex <= $this->endColumnIndex)) {
++$this->startColumnIndex;
}
if ($this->startColumn > $this->endColumn) {
if ($this->startColumnIndex > $this->endColumnIndex) {
throw new PhpSpreadsheetException('No cells exist within the specified range');
}
while ((!$this->subject->cellExistsByColumnAndRow($this->endColumn, $this->rowIndex)) && ($this->endColumn >= $this->startColumn)) {
--$this->endColumn;
while ((!$this->worksheet->cellExistsByColumnAndRow($this->endColumnIndex, $this->rowIndex)) && ($this->endColumnIndex >= $this->startColumnIndex)) {
--$this->endColumnIndex;
}
if ($this->endColumn < $this->startColumn) {
if ($this->endColumnIndex < $this->startColumnIndex) {
throw new PhpSpreadsheetException('No cells exist within the specified range');
}
}

View File

@ -1123,15 +1123,15 @@ class Worksheet implements IComparable
/**
* Set a cell value by using numeric cell coordinates.
*
* @param int $pColumn Numeric column coordinate of the cell (A = 0)
* @param int $pRow Numeric row coordinate of the cell
* @param mixed $pValue Value of the cell
* @param int $columnIndex Numeric column coordinate of the cell
* @param int $row Numeric row coordinate of the cell
* @param mixed $value Value of the cell
*
* @return Worksheet
*/
public function setCellValueByColumnAndRow($pColumn, $pRow, $pValue)
public function setCellValueByColumnAndRow($columnIndex, $row, $value)
{
$this->getCellByColumnAndRow($pColumn, $pRow)->setValue($pValue);
$this->getCellByColumnAndRow($columnIndex, $row)->setValue($value);
return $this;
}
@ -1156,16 +1156,16 @@ class Worksheet implements IComparable
/**
* Set a cell value by using numeric cell coordinates.
*
* @param int $pColumn Numeric column coordinate of the cell (A = 0)
* @param int $pRow Numeric row coordinate of the cell
* @param mixed $pValue Value of the cell
* @param string $pDataType Explicit data type, see DataType::TYPE_*
* @param int $columnIndex Numeric column coordinate of the cell
* @param int $row Numeric row coordinate of the cell
* @param mixed $value Value of the cell
* @param string $dataType Explicit data type, see DataType::TYPE_*
*
* @return Worksheet
*/
public function setCellValueExplicitByColumnAndRow($pColumn, $pRow, $pValue, $pDataType)
public function setCellValueExplicitByColumnAndRow($columnIndex, $row, $value, $dataType)
{
$this->getCellByColumnAndRow($pColumn, $pRow)->setValueExplicit($pValue, $pDataType);
$this->getCellByColumnAndRow($columnIndex, $row)->setValueExplicit($value, $dataType);
return $this;
}
@ -1222,17 +1222,17 @@ class Worksheet implements IComparable
/**
* Get cell at a specific coordinate by using numeric cell coordinates.
*
* @param string $pColumn Numeric column coordinate of the cell
* @param string $pRow Numeric row coordinate of the cell
* @param int $columnIndex Numeric column coordinate of the cell
* @param int $row Numeric row coordinate of the cell
* @param bool $createIfNotExists Flag indicating whether a new cell should be created if it doesn't
* already exist, or a null should be returned instead
*
* @return null|Cell Cell that was found/created or null
*/
public function getCellByColumnAndRow($pColumn, $pRow, $createIfNotExists = true)
public function getCellByColumnAndRow($columnIndex, $row, $createIfNotExists = true)
{
$columnLetter = Coordinate::stringFromColumnIndex($pColumn);
$coordinate = $columnLetter . $pRow;
$columnLetter = Coordinate::stringFromColumnIndex($columnIndex);
$coordinate = $columnLetter . $row;
if ($this->cellCollection->has($coordinate)) {
return $this->cellCollection->get($coordinate);
@ -1330,14 +1330,14 @@ class Worksheet implements IComparable
/**
* Cell at a specific coordinate by using numeric cell coordinates exists?
*
* @param string $pColumn Numeric column coordinate of the cell (A = 0)
* @param string $pRow Numeric row coordinate of the cell
* @param int $columnIndex Numeric column coordinate of the cell
* @param int $row Numeric row coordinate of the cell
*
* @return bool
*/
public function cellExistsByColumnAndRow($pColumn, $pRow)
public function cellExistsByColumnAndRow($columnIndex, $row)
{
return $this->cellExists(Coordinate::stringFromColumnIndex($pColumn) . $pRow);
return $this->cellExists(Coordinate::stringFromColumnIndex($columnIndex) . $row);
}
/**
@ -1397,13 +1397,13 @@ class Worksheet implements IComparable
/**
* Get column dimension at a specific column by using numeric cell coordinates.
*
* @param int $pColumn Numeric column coordinate of the cell (A = 0)
* @param int $columnIndex Numeric column coordinate of the cell
*
* @return ColumnDimension
*/
public function getColumnDimensionByColumn($pColumn)
public function getColumnDimensionByColumn($columnIndex)
{
return $this->getColumnDimension(Coordinate::stringFromColumnIndex($pColumn));
return $this->getColumnDimension(Coordinate::stringFromColumnIndex($columnIndex));
}
/**
@ -1511,24 +1511,24 @@ class Worksheet implements IComparable
/**
* Get style for cell by using numeric cell coordinates.
*
* @param int $pColumn Numeric column coordinate of the cell (A = 0)
* @param int $pRow Numeric row coordinate of the cell
* @param int pColumn2 Numeric column coordinate of the range cell (A = 0)
* @param int pRow2 Numeric row coordinate of the range cell
* @param null|mixed $pColumn2
* @param null|mixed $pRow2
* @param int $columnIndex1 Numeric column coordinate of the cell
* @param int $row1 Numeric row coordinate of the cell
* @param int $columnIndex2 Numeric column coordinate of the range cell
* @param int $row2 Numeric row coordinate of the range cell
* @param null|int $columnIndex2
* @param null|int $row2
*
* @return Style
*/
public function getStyleByColumnAndRow($pColumn, $pRow, $pColumn2 = null, $pRow2 = null)
public function getStyleByColumnAndRow($columnIndex1, $row1, $columnIndex2 = null, $row2 = null)
{
if ($pColumn2 !== null && $pRow2 !== null) {
$cellRange = Coordinate::stringFromColumnIndex($pColumn) . $pRow . ':' . Coordinate::stringFromColumnIndex($pColumn2) . $pRow2;
if ($columnIndex2 !== null && $row2 !== null) {
$cellRange = Coordinate::stringFromColumnIndex($columnIndex1) . $row1 . ':' . Coordinate::stringFromColumnIndex($columnIndex2) . $row2;
return $this->getStyle($cellRange);
}
return $this->getStyle(Coordinate::stringFromColumnIndex($pColumn) . $pRow);
return $this->getStyle(Coordinate::stringFromColumnIndex($columnIndex1) . $row1);
}
/**
@ -1569,7 +1569,7 @@ class Worksheet implements IComparable
// Loop through cells and apply styles
for ($col = $rangeStart[0]; $col <= $rangeEnd[0]; ++$col) {
for ($row = $rangeStart[1]; $row <= $rangeEnd[1]; ++$row) {
$this->getCell(Coordinate::stringFromColumnIndex($col - 1) . $row)->setXfIndex($xfIndex);
$this->getCell(Coordinate::stringFromColumnIndex($col) . $row)->setXfIndex($xfIndex);
}
}
@ -1609,7 +1609,7 @@ class Worksheet implements IComparable
// Loop through cells and apply styles
for ($col = $rangeStart[0]; $col <= $rangeEnd[0]; ++$col) {
for ($row = $rangeStart[1]; $row <= $rangeEnd[1]; ++$row) {
$this->setConditionalStyles(Coordinate::stringFromColumnIndex($col - 1) . $row, $pCellStyle);
$this->setConditionalStyles(Coordinate::stringFromColumnIndex($col) . $row, $pCellStyle);
}
}
@ -1649,15 +1649,15 @@ class Worksheet implements IComparable
/**
* Set break on a cell by using numeric cell coordinates.
*
* @param int $pColumn Numeric column coordinate of the cell (A = 0)
* @param int $pRow Numeric row coordinate of the cell
* @param int $pBreak Break type (type of Worksheet::BREAK_*)
* @param int $columnIndex Numeric column coordinate of the cell
* @param int $row Numeric row coordinate of the cell
* @param int $break Break type (type of Worksheet::BREAK_*)
*
* @return Worksheet
*/
public function setBreakByColumnAndRow($pColumn, $pRow, $pBreak)
public function setBreakByColumnAndRow($columnIndex, $row, $break)
{
return $this->setBreak(Coordinate::stringFromColumnIndex($pColumn) . $pRow, $pBreak);
return $this->setBreak(Coordinate::stringFromColumnIndex($columnIndex) . $row, $break);
}
/**
@ -1715,18 +1715,18 @@ class Worksheet implements IComparable
/**
* Set merge on a cell range by using numeric cell coordinates.
*
* @param int $pColumn1 Numeric column coordinate of the first cell (A = 0)
* @param int $pRow1 Numeric row coordinate of the first cell
* @param int $pColumn2 Numeric column coordinate of the last cell (A = 0)
* @param int $pRow2 Numeric row coordinate of the last cell
* @param int $columnIndex1 Numeric column coordinate of the first cell
* @param int $row1 Numeric row coordinate of the first cell
* @param int $columnIndex2 Numeric column coordinate of the last cell
* @param int $row2 Numeric row coordinate of the last cell
*
* @throws Exception
*
* @return Worksheet
*/
public function mergeCellsByColumnAndRow($pColumn1, $pRow1, $pColumn2, $pRow2)
public function mergeCellsByColumnAndRow($columnIndex1, $row1, $columnIndex2, $row2)
{
$cellRange = Coordinate::stringFromColumnIndex($pColumn1) . $pRow1 . ':' . Coordinate::stringFromColumnIndex($pColumn2) . $pRow2;
$cellRange = Coordinate::stringFromColumnIndex($columnIndex1) . $row1 . ':' . Coordinate::stringFromColumnIndex($columnIndex2) . $row2;
return $this->mergeCells($cellRange);
}
@ -1761,18 +1761,18 @@ class Worksheet implements IComparable
/**
* Remove merge on a cell range by using numeric cell coordinates.
*
* @param int $pColumn1 Numeric column coordinate of the first cell (A = 0)
* @param int $pRow1 Numeric row coordinate of the first cell
* @param int $pColumn2 Numeric column coordinate of the last cell (A = 0)
* @param int $pRow2 Numeric row coordinate of the last cell
* @param int $columnIndex1 Numeric column coordinate of the first cell
* @param int $row1 Numeric row coordinate of the first cell
* @param int $columnIndex2 Numeric column coordinate of the last cell
* @param int $row2 Numeric row coordinate of the last cell
*
* @throws Exception
*
* @return Worksheet
*/
public function unmergeCellsByColumnAndRow($pColumn1, $pRow1, $pColumn2, $pRow2)
public function unmergeCellsByColumnAndRow($columnIndex1, $row1, $columnIndex2, $row2)
{
$cellRange = Coordinate::stringFromColumnIndex($pColumn1) . $pRow1 . ':' . Coordinate::stringFromColumnIndex($pColumn2) . $pRow2;
$cellRange = Coordinate::stringFromColumnIndex($columnIndex1) . $row1 . ':' . Coordinate::stringFromColumnIndex($columnIndex2) . $row2;
return $this->unmergeCells($cellRange);
}
@ -1828,22 +1828,22 @@ class Worksheet implements IComparable
/**
* Set protection on a cell range by using numeric cell coordinates.
*
* @param int $pColumn1 Numeric column coordinate of the first cell (A = 0)
* @param int $pRow1 Numeric row coordinate of the first cell
* @param int $pColumn2 Numeric column coordinate of the last cell (A = 0)
* @param int $pRow2 Numeric row coordinate of the last cell
* @param string $pPassword Password to unlock the protection
* @param bool $pAlreadyHashed If the password has already been hashed, set this to true
* @param int $columnIndex1 Numeric column coordinate of the first cell
* @param int $row1 Numeric row coordinate of the first cell
* @param int $columnIndex2 Numeric column coordinate of the last cell
* @param int $row2 Numeric row coordinate of the last cell
* @param string $password Password to unlock the protection
* @param bool $alreadyHashed If the password has already been hashed, set this to true
*
* @throws Exception
*
* @return Worksheet
*/
public function protectCellsByColumnAndRow($pColumn1, $pRow1, $pColumn2, $pRow2, $pPassword, $pAlreadyHashed = false)
public function protectCellsByColumnAndRow($columnIndex1, $row1, $columnIndex2, $row2, $password, $alreadyHashed = false)
{
$cellRange = Coordinate::stringFromColumnIndex($pColumn1) . $pRow1 . ':' . Coordinate::stringFromColumnIndex($pColumn2) . $pRow2;
$cellRange = Coordinate::stringFromColumnIndex($columnIndex1) . $row1 . ':' . Coordinate::stringFromColumnIndex($columnIndex2) . $row2;
return $this->protectCells($cellRange, $pPassword, $pAlreadyHashed);
return $this->protectCells($cellRange, $password, $alreadyHashed);
}
/**
@ -1872,18 +1872,18 @@ class Worksheet implements IComparable
/**
* Remove protection on a cell range by using numeric cell coordinates.
*
* @param int $pColumn1 Numeric column coordinate of the first cell (A = 0)
* @param int $pRow1 Numeric row coordinate of the first cell
* @param int $pColumn2 Numeric column coordinate of the last cell (A = 0)
* @param int $pRow2 Numeric row coordinate of the last cell
* @param int $columnIndex1 Numeric column coordinate of the first cell
* @param int $row1 Numeric row coordinate of the first cell
* @param int $columnIndex2 Numeric column coordinate of the last cell
* @param int $row2 Numeric row coordinate of the last cell
*
* @throws Exception
*
* @return Worksheet
*/
public function unprotectCellsByColumnAndRow($pColumn1, $pRow1, $pColumn2, $pRow2)
public function unprotectCellsByColumnAndRow($columnIndex1, $row1, $columnIndex2, $row2)
{
$cellRange = Coordinate::stringFromColumnIndex($pColumn1) . $pRow1 . ':' . Coordinate::stringFromColumnIndex($pColumn2) . $pRow2;
$cellRange = Coordinate::stringFromColumnIndex($columnIndex1) . $row1 . ':' . Coordinate::stringFromColumnIndex($columnIndex2) . $row2;
return $this->unprotectCells($cellRange);
}
@ -1932,21 +1932,21 @@ class Worksheet implements IComparable
/**
* Set Autofilter Range by using numeric cell coordinates.
*
* @param int $pColumn1 Numeric column coordinate of the first cell (A = 0)
* @param int $pRow1 Numeric row coordinate of the first cell
* @param int $pColumn2 Numeric column coordinate of the second cell (A = 0)
* @param int $pRow2 Numeric row coordinate of the second cell
* @param int $columnIndex1 Numeric column coordinate of the first cell
* @param int $row1 Numeric row coordinate of the first cell
* @param int $columnIndex2 Numeric column coordinate of the second cell
* @param int $row2 Numeric row coordinate of the second cell
*
* @throws Exception
*
* @return Worksheet
*/
public function setAutoFilterByColumnAndRow($pColumn1, $pRow1, $pColumn2, $pRow2)
public function setAutoFilterByColumnAndRow($columnIndex1, $row1, $columnIndex2, $row2)
{
return $this->setAutoFilter(
Coordinate::stringFromColumnIndex($pColumn1) . $pRow1
Coordinate::stringFromColumnIndex($columnIndex1) . $row1
. ':' .
Coordinate::stringFromColumnIndex($pColumn2) . $pRow2
Coordinate::stringFromColumnIndex($columnIndex2) . $row2
);
}
@ -2002,16 +2002,16 @@ class Worksheet implements IComparable
/**
* Freeze Pane by using numeric cell coordinates.
*
* @param int $pColumn Numeric column coordinate of the cell (A = 0)
* @param int $pRow Numeric row coordinate of the cell
* @param int $columnIndex Numeric column coordinate of the cell
* @param int $row Numeric row coordinate of the cell
*
* @throws Exception
*
* @return Worksheet
*/
public function freezePaneByColumnAndRow($pColumn, $pRow)
public function freezePaneByColumnAndRow($columnIndex, $row)
{
return $this->freezePane(Coordinate::stringFromColumnIndex($pColumn) . $pRow);
return $this->freezePane(Coordinate::stringFromColumnIndex($columnIndex) . $row);
}
/**
@ -2071,20 +2071,20 @@ class Worksheet implements IComparable
/**
* Insert a new column, updating all possible related data.
*
* @param int $pBefore Insert before this one (numeric column coordinate of the cell, A = 0)
* @param int $beforeColumnIndex Insert before this one (numeric column coordinate of the cell)
* @param int $pNumCols Number of columns to insert
*
* @throws Exception
*
* @return Worksheet
*/
public function insertNewColumnBeforeByIndex($pBefore, $pNumCols = 1)
public function insertNewColumnBeforeByIndex($beforeColumnIndex, $pNumCols = 1)
{
if ($pBefore >= 0) {
return $this->insertNewColumnBefore(Coordinate::stringFromColumnIndex($pBefore), $pNumCols);
if ($beforeColumnIndex >= 1) {
return $this->insertNewColumnBefore(Coordinate::stringFromColumnIndex($beforeColumnIndex), $pNumCols);
}
throw new Exception('Columns can only be inserted before at least column A (0).');
throw new Exception('Columns can only be inserted before at least column A (1).');
}
/**
@ -2128,12 +2128,12 @@ class Worksheet implements IComparable
{
if (!is_numeric($pColumn)) {
$highestColumn = $this->getHighestDataColumn();
$pColumn = Coordinate::stringFromColumnIndex(Coordinate::columnIndexFromString($pColumn) - 1 + $pNumCols);
$pColumn = Coordinate::stringFromColumnIndex(Coordinate::columnIndexFromString($pColumn) + $pNumCols);
$objReferenceHelper = ReferenceHelper::getInstance();
$objReferenceHelper->insertNewBefore($pColumn . '1', -$pNumCols, 0, $this);
for ($c = 0; $c < $pNumCols; ++$c) {
$this->getCellCollection()->removeColumn($highestColumn);
$highestColumn = Coordinate::stringFromColumnIndex(Coordinate::columnIndexFromString($highestColumn) - 2);
$highestColumn = Coordinate::stringFromColumnIndex(Coordinate::columnIndexFromString($highestColumn) - 1);
}
} else {
throw new Exception('Column references should not be numeric.');
@ -2145,20 +2145,20 @@ class Worksheet implements IComparable
/**
* Remove a column, updating all possible related data.
*
* @param int $pColumn Remove starting with this one (numeric column coordinate of the cell A = 0)
* @param int $pNumCols Number of columns to remove
* @param int $columnIndex Remove starting with this one (numeric column coordinate of the cell)
* @param int $numColumns Number of columns to remove
*
* @throws Exception
*
* @return Worksheet
*/
public function removeColumnByIndex($pColumn, $pNumCols = 1)
public function removeColumnByIndex($columnIndex, $numColumns = 1)
{
if ($pColumn >= 0) {
return $this->removeColumn(Coordinate::stringFromColumnIndex($pColumn), $pNumCols);
if ($columnIndex >= 1) {
return $this->removeColumn(Coordinate::stringFromColumnIndex($columnIndex), $numColumns);
}
throw new Exception('Columns to be deleted should at least start from column 0');
throw new Exception('Columns to be deleted should at least start from column A (1)');
}
/**
@ -2343,14 +2343,14 @@ class Worksheet implements IComparable
/**
* Get comment for cell by using numeric cell coordinates.
*
* @param int $pColumn Numeric column coordinate of the cell (A = 0)
* @param int $pRow Numeric row coordinate of the cell
* @param int $columnIndex Numeric column coordinate of the cell
* @param int $row Numeric row coordinate of the cell
*
* @return Comment
*/
public function getCommentByColumnAndRow($pColumn, $pRow)
public function getCommentByColumnAndRow($columnIndex, $row)
{
return $this->getComment(Coordinate::stringFromColumnIndex($pColumn) . $pRow);
return $this->getComment(Coordinate::stringFromColumnIndex($columnIndex) . $row);
}
/**
@ -2425,16 +2425,16 @@ class Worksheet implements IComparable
/**
* Selected cell by using numeric cell coordinates.
*
* @param int $pColumn Numeric column coordinate of the cell (A = 0)
* @param int $pRow Numeric row coordinate of the cell
* @param int $columnIndex Numeric column coordinate of the cell
* @param int $row Numeric row coordinate of the cell
*
* @throws Exception
*
* @return Worksheet
*/
public function setSelectedCellByColumnAndRow($pColumn, $pRow)
public function setSelectedCellByColumnAndRow($columnIndex, $row)
{
return $this->setSelectedCells(Coordinate::stringFromColumnIndex($pColumn) . $pRow);
return $this->setSelectedCells(Coordinate::stringFromColumnIndex($columnIndex) . $row);
}
/**
@ -2524,9 +2524,9 @@ class Worksheet implements IComparable
$returnValue = [];
// Identify the range that we need to extract from the worksheet
list($rangeStart, $rangeEnd) = Coordinate::rangeBoundaries($pRange);
$minCol = Coordinate::stringFromColumnIndex($rangeStart[0] - 1);
$minCol = Coordinate::stringFromColumnIndex($rangeStart[0]);
$minRow = $rangeStart[1];
$maxCol = Coordinate::stringFromColumnIndex($rangeEnd[0] - 1);
$maxCol = Coordinate::stringFromColumnIndex($rangeEnd[0]);
$maxRow = $rangeEnd[1];
++$maxCol;
@ -2653,7 +2653,7 @@ class Worksheet implements IComparable
}
/**
* Run PhpSpreadsheet garabage collector.
* Run PhpSpreadsheet garbage collector.
*
* @return Worksheet
*/
@ -2678,10 +2678,10 @@ class Worksheet implements IComparable
}
// Cache values
if ($highestColumn < 0) {
if ($highestColumn < 1) {
$this->cachedHighestColumn = 'A';
} else {
$this->cachedHighestColumn = Coordinate::stringFromColumnIndex(--$highestColumn);
$this->cachedHighestColumn = Coordinate::stringFromColumnIndex($highestColumn);
}
$this->cachedHighestRow = $highestRow;

View File

@ -434,9 +434,9 @@ class Html extends BaseWriter
// Get worksheet dimension
$dimension = explode(':', $sheet->calculateWorksheetDimension());
$dimension[0] = Coordinate::coordinateFromString($dimension[0]);
$dimension[0][0] = Coordinate::columnIndexFromString($dimension[0][0]) - 1;
$dimension[0][0] = Coordinate::columnIndexFromString($dimension[0][0]);
$dimension[1] = Coordinate::coordinateFromString($dimension[1]);
$dimension[1][0] = Coordinate::columnIndexFromString($dimension[1][0]) - 1;
$dimension[1][0] = Coordinate::columnIndexFromString($dimension[1][0]);
// row min,max
$rowMin = $dimension[0][1];
@ -476,14 +476,15 @@ class Html extends BaseWriter
// Start a new rowData
$rowData = [];
// Loop through columns
$column = $dimension[0][0] - 1;
while ($column++ < $dimension[1][0]) {
$column = $dimension[0][0];
while ($column <= $dimension[1][0]) {
// Cell exists?
if ($sheet->cellExistsByColumnAndRow($column, $row)) {
$rowData[$column] = Coordinate::stringFromColumnIndex($column) . $row;
} else {
$rowData[$column] = '';
}
++$column;
}
$html .= $this->generateRow($sheet, $rowData, $row - 1, $cellType);
}
@ -1210,7 +1211,7 @@ class Html extends BaseWriter
$colNum = 0;
foreach ($pValues as $cellAddress) {
$cell = ($cellAddress > '') ? $pSheet->getCell($cellAddress) : '';
$coordinate = Coordinate::stringFromColumnIndex($colNum) . ($pRow + 1);
$coordinate = Coordinate::stringFromColumnIndex($colNum + 1) . ($pRow + 1);
if (!$this->useInlineCss) {
$cssClass = 'column' . $colNum;
} else {
@ -1340,7 +1341,7 @@ class Html extends BaseWriter
// Also apply style from last cell in merge to fix borders -
// relies on !important for non-none border declarations in createCSSStyleBorder
$endCellCoord = Coordinate::stringFromColumnIndex($colNum + $colSpan - 1) . ($pRow + $rowSpan);
$endCellCoord = Coordinate::stringFromColumnIndex($colNum + $colSpan) . ($pRow + $rowSpan);
if (!$this->useInlineCss) {
$cssClass .= ' style' . $pSheet->getCell($endCellCoord)->getXfIndex();
}

View File

@ -334,7 +334,7 @@ class Xls extends BaseWriter
// create an Drawing Object for the dropdown
$oDrawing = new BaseDrawing();
// get the coordinates of drawing
$cDrawing = Coordinate::stringFromColumnIndex($iInc - 1) . $rangeBounds[0][1];
$cDrawing = Coordinate::stringFromColumnIndex($iInc) . $rangeBounds[0][1];
$oDrawing->setCoordinates($cDrawing);
$oDrawing->setWorksheet($sheet);
@ -363,7 +363,7 @@ class Xls extends BaseWriter
$spContainer->setOPT(0x03BF, 0x000A0000); // Group Shape -> fPrint
// set coordinates and offsets, client anchor
$endCoordinates = Coordinate::stringFromColumnIndex($iInc - 1);
$endCoordinates = Coordinate::stringFromColumnIndex($iInc);
$endCoordinates .= $rangeBounds[0][1] + 1;
$spContainer->setStartCoordinates($cDrawing);

View File

@ -310,7 +310,7 @@ class Worksheet extends BIFFwriter
$width = $defaultWidth;
$columnLetter = Coordinate::stringFromColumnIndex($i);
$columnLetter = Coordinate::stringFromColumnIndex($i + 1);
if (isset($columnDimensions[$columnLetter])) {
$columnDimension = $columnDimensions[$columnLetter];
if ($columnDimension->getWidth() >= 0) {
@ -2288,7 +2288,7 @@ class Worksheet extends BIFFwriter
$row_end = $row_start; // Row containing bottom right corner of object
// Zero the specified offset if greater than the cell dimensions
if ($x1 >= Xls::sizeCol($this->phpSheet, Coordinate::stringFromColumnIndex($col_start))) {
if ($x1 >= Xls::sizeCol($this->phpSheet, Coordinate::stringFromColumnIndex($col_start + 1))) {
$x1 = 0;
}
if ($y1 >= Xls::sizeRow($this->phpSheet, $row_start + 1)) {
@ -2299,8 +2299,8 @@ class Worksheet extends BIFFwriter
$height = $height + $y1 - 1;
// Subtract the underlying cell widths to find the end cell of the image
while ($width >= Xls::sizeCol($this->phpSheet, Coordinate::stringFromColumnIndex($col_end))) {
$width -= Xls::sizeCol($this->phpSheet, Coordinate::stringFromColumnIndex($col_end));
while ($width >= Xls::sizeCol($this->phpSheet, Coordinate::stringFromColumnIndex($col_end + 1))) {
$width -= Xls::sizeCol($this->phpSheet, Coordinate::stringFromColumnIndex($col_end + 1));
++$col_end;
}
@ -2313,10 +2313,10 @@ class Worksheet extends BIFFwriter
// Bitmap isn't allowed to start or finish in a hidden cell, i.e. a cell
// with zero eight or width.
//
if (Xls::sizeCol($this->phpSheet, Coordinate::stringFromColumnIndex($col_start)) == 0) {
if (Xls::sizeCol($this->phpSheet, Coordinate::stringFromColumnIndex($col_start + 1)) == 0) {
return;
}
if (Xls::sizeCol($this->phpSheet, Coordinate::stringFromColumnIndex($col_end)) == 0) {
if (Xls::sizeCol($this->phpSheet, Coordinate::stringFromColumnIndex($col_end + 1)) == 0) {
return;
}
if (Xls::sizeRow($this->phpSheet, $row_start + 1) == 0) {
@ -2327,9 +2327,9 @@ class Worksheet extends BIFFwriter
}
// Convert the pixel values to the percentage value expected by Excel
$x1 = $x1 / Xls::sizeCol($this->phpSheet, Coordinate::stringFromColumnIndex($col_start)) * 1024;
$x1 = $x1 / Xls::sizeCol($this->phpSheet, Coordinate::stringFromColumnIndex($col_start + 1)) * 1024;
$y1 = $y1 / Xls::sizeRow($this->phpSheet, $row_start + 1) * 256;
$x2 = $width / Xls::sizeCol($this->phpSheet, Coordinate::stringFromColumnIndex($col_end)) * 1024; // Distance to right side of object
$x2 = $width / Xls::sizeCol($this->phpSheet, Coordinate::stringFromColumnIndex($col_end + 1)) * 1024; // Distance to right side of object
$y2 = $height / Xls::sizeRow($this->phpSheet, $row_end + 1) * 256; // Distance to bottom of object
$this->writeObjPicture($col_start, $x1, $row_start, $y1, $col_end, $x2, $row_end, $y2);

View File

@ -12,11 +12,15 @@ class CoordinateTest extends TestCase
* @dataProvider providerColumnString
*
* @param mixed $expectedResult
* @param mixed $string
*/
public function testColumnIndexFromString($expectedResult, ...$args)
public function testColumnIndexFromString($expectedResult, $string)
{
$result = Coordinate::columnIndexFromString(...$args);
self::assertEquals($expectedResult, $result);
$columnIndex = Coordinate::columnIndexFromString($string);
self::assertEquals($expectedResult, $columnIndex);
$stringBack = Coordinate::stringFromColumnIndex($columnIndex);
self::assertEquals($stringBack, $string, 'should be able to get the original input with opposite method');
}
public function providerColumnString()
@ -58,11 +62,15 @@ class CoordinateTest extends TestCase
* @dataProvider providerColumnIndex
*
* @param mixed $expectedResult
* @param int $columnIndex
*/
public function testStringFromColumnIndex($expectedResult, ...$args)
public function testStringFromColumnIndex($expectedResult, $columnIndex)
{
$result = Coordinate::stringFromColumnIndex(...$args);
self::assertEquals($expectedResult, $result);
$string = Coordinate::stringFromColumnIndex($columnIndex);
self::assertEquals($expectedResult, $string);
$columnIndexBack = Coordinate::columnIndexFromString($string);
self::assertEquals($columnIndexBack, $columnIndex, 'should be able to get the original input with opposite method');
}
public function providerColumnIndex()

View File

@ -1,6 +1,6 @@
<?php
namespace PhpOffice\PhpSpreadsheetTests\Sample;
namespace PhpOffice\PhpSpreadsheetTests\Helper;
use PhpOffice\PhpSpreadsheet\Helper\Sample;
use PHPUnit\Framework\TestCase;

View File

@ -3,50 +3,50 @@
return [
[
'A',
0,
1,
],
[
'Z',
25,
],
[
'AA',
26,
],
[
'AB',
'AA',
27,
],
[
'AZ',
51,
'AB',
28,
],
[
'BA',
'AZ',
52,
],
[
'BZ',
77,
'BA',
53,
],
[
'CA',
'BZ',
78,
],
[
'CA',
79,
],
[
'IV',
255,
256,
],
[
'ZZ',
701,
],
[
'AAA',
702,
],
[
'AAA',
703,
],
[
'BAA',
1378,
1379,
],
];