From 8d7602059006677a739c67902a434b70aa7b234c Mon Sep 17 00:00:00 2001 From: Adrien Crivelli Date: Sat, 25 Nov 2017 19:26:41 +0900 Subject: [PATCH] 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 --- CHANGELOG.md | 2 + docs/topics/accessing-cells.md | 22 +- docs/topics/migration-from-PHPExcel.md | 63 ++++++ samples/Basic/40_Duplicate_style.php | 2 +- .../Calculation/Calculation.php | 4 +- src/PhpSpreadsheet/Calculation/LookupRef.php | 6 +- src/PhpSpreadsheet/Cell/Coordinate.php | 14 +- src/PhpSpreadsheet/Collection/Cells.php | 2 +- src/PhpSpreadsheet/Reader/Csv.php | 2 +- src/PhpSpreadsheet/Reader/Gnumeric.php | 16 +- src/PhpSpreadsheet/Reader/Ods.php | 4 +- src/PhpSpreadsheet/Reader/Slk.php | 16 +- src/PhpSpreadsheet/Reader/Xls.php | 62 +++--- src/PhpSpreadsheet/Reader/Xls/Escher.php | 4 +- src/PhpSpreadsheet/Reader/Xlsx.php | 20 +- src/PhpSpreadsheet/Reader/Xml.php | 10 +- src/PhpSpreadsheet/ReferenceHelper.php | 33 ++- src/PhpSpreadsheet/Shared/Xls.php | 6 +- src/PhpSpreadsheet/Style/Style.php | 4 +- src/PhpSpreadsheet/Worksheet/AutoFilter.php | 2 +- src/PhpSpreadsheet/Worksheet/CellIterator.php | 11 +- .../Worksheet/ColumnCellIterator.php | 51 +++-- .../Worksheet/ColumnIterator.php | 58 ++--- src/PhpSpreadsheet/Worksheet/PageSetup.php | 2 +- .../Worksheet/RowCellIterator.php | 74 ++++--- src/PhpSpreadsheet/Worksheet/Worksheet.php | 208 +++++++++--------- src/PhpSpreadsheet/Writer/Html.php | 13 +- src/PhpSpreadsheet/Writer/Xls.php | 4 +- src/PhpSpreadsheet/Writer/Xls/Worksheet.php | 16 +- .../Cell/CoordinateTest.php | 20 +- .../PhpSpreadsheetTests/Helper/SampleTest.php | 2 +- tests/data/ColumnIndex.php | 36 +-- 32 files changed, 431 insertions(+), 358 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 04bce8e5..a22b9f34 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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). diff --git a/docs/topics/accessing-cells.md b/docs/topics/accessing-cells.md index 7cc7ed73..241690d5 100644 --- a/docs/topics/accessing-cells.md +++ b/docs/topics/accessing-cells.md @@ -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 cell’s value can +the worksheet using the `getCellByColumnAndRow()` method. A cell’s 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 '' . "\n"; for ($row = 1; $row <= $highestRow; ++$row) { echo '' . PHP_EOL; - for ($col = 0; $col <= $highestColumnIndex; ++$col) { - echo '' . PHP_EOL; + for ($col = 1; $col <= $highestColumnIndex; ++$col) { + $value = $worksheet->getCellByColumnAndRow($col, $row)->getValue(); + echo '' . PHP_EOL; } echo '' . PHP_EOL; } diff --git a/docs/topics/migration-from-PHPExcel.md b/docs/topics/migration-from-PHPExcel.md index 5d6b5f6e..cb0025d6 100644 --- a/docs/topics/migration-from-PHPExcel.md +++ b/docs/topics/migration-from-PHPExcel.md @@ -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()` diff --git a/samples/Basic/40_Duplicate_style.php b/samples/Basic/40_Duplicate_style.php index 2bddbdaf..a2dc5f5f 100644 --- a/samples/Basic/40_Duplicate_style.php +++ b/samples/Basic/40_Duplicate_style.php @@ -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]; diff --git a/src/PhpSpreadsheet/Calculation/Calculation.php b/src/PhpSpreadsheet/Calculation/Calculation.php index 1d387301..b3665abd 100644 --- a/src/PhpSpreadsheet/Calculation/Calculation.php +++ b/src/PhpSpreadsheet/Calculation/Calculation.php @@ -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); diff --git a/src/PhpSpreadsheet/Calculation/LookupRef.php b/src/PhpSpreadsheet/Calculation/LookupRef.php index e8de720c..bd199663 100644 --- a/src/PhpSpreadsheet/Calculation/LookupRef.php +++ b/src/PhpSpreadsheet/Calculation/LookupRef.php @@ -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)) { diff --git a/src/PhpSpreadsheet/Cell/Coordinate.php b/src/PhpSpreadsheet/Cell/Coordinate.php index 96ff39a8..82ba5a98 100644 --- a/src/PhpSpreadsheet/Cell/Coordinate.php +++ b/src/PhpSpreadsheet/Cell/Coordinate.php @@ -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; diff --git a/src/PhpSpreadsheet/Collection/Cells.php b/src/PhpSpreadsheet/Collection/Cells.php index 8e6fb917..fc81a976 100644 --- a/src/PhpSpreadsheet/Collection/Cells.php +++ b/src/PhpSpreadsheet/Collection/Cells.php @@ -248,7 +248,7 @@ class Cells $columnList[] = Coordinate::columnIndexFromString($c); } - return Coordinate::stringFromColumnIndex(max($columnList) - 1); + return Coordinate::stringFromColumnIndex(max($columnList) + 1); } /** diff --git a/src/PhpSpreadsheet/Reader/Csv.php b/src/PhpSpreadsheet/Reader/Csv.php index 388345c1..954b9e8d 100644 --- a/src/PhpSpreadsheet/Reader/Csv.php +++ b/src/PhpSpreadsheet/Reader/Csv.php @@ -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 diff --git a/src/PhpSpreadsheet/Reader/Gnumeric.php b/src/PhpSpreadsheet/Reader/Gnumeric.php index 513246ce..617e23ef 100644 --- a/src/PhpSpreadsheet/Reader/Gnumeric.php +++ b/src/PhpSpreadsheet/Reader/Gnumeric.php @@ -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; } } diff --git a/src/PhpSpreadsheet/Reader/Ods.php b/src/PhpSpreadsheet/Reader/Ods.php index 02050c96..b433c2d9 100644 --- a/src/PhpSpreadsheet/Reader/Ods.php +++ b/src/PhpSpreadsheet/Reader/Ods.php @@ -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; diff --git a/src/PhpSpreadsheet/Reader/Slk.php b/src/PhpSpreadsheet/Reader/Slk.php index d9d1178b..7892bb0e 100644 --- a/src/PhpSpreadsheet/Reader/Slk.php +++ b/src/PhpSpreadsheet/Reader/Slk.php @@ -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); diff --git a/src/PhpSpreadsheet/Reader/Xls.php b/src/PhpSpreadsheet/Reader/Xls.php index 443fc705..a8cfb8e2 100644 --- a/src/PhpSpreadsheet/Reader/Xls.php +++ b/src/PhpSpreadsheet/Reader/Xls.php @@ -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) diff --git a/src/PhpSpreadsheet/Reader/Xls/Escher.php b/src/PhpSpreadsheet/Reader/Xls/Escher.php index 941618e0..0e88936c 100644 --- a/src/PhpSpreadsheet/Reader/Xls/Escher.php +++ b/src/PhpSpreadsheet/Reader/Xls/Escher.php @@ -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); diff --git a/src/PhpSpreadsheet/Reader/Xlsx.php b/src/PhpSpreadsheet/Reader/Xlsx.php index 3870498d..1c249cae 100644 --- a/src/PhpSpreadsheet/Reader/Xlsx.php +++ b/src/PhpSpreadsheet/Reader/Xlsx.php @@ -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; diff --git a/src/PhpSpreadsheet/Reader/Xml.php b/src/PhpSpreadsheet/Reader/Xml.php index c08a84a7..b0173836 100644 --- a/src/PhpSpreadsheet/Reader/Xml.php +++ b/src/PhpSpreadsheet/Reader/Xml.php @@ -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])); } } diff --git a/src/PhpSpreadsheet/ReferenceHelper.php b/src/PhpSpreadsheet/ReferenceHelper.php index 1faafed5..bfa14108 100644 --- a/src/PhpSpreadsheet/ReferenceHelper.php +++ b/src/PhpSpreadsheet/ReferenceHelper.php @@ -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 diff --git a/src/PhpSpreadsheet/Shared/Xls.php b/src/PhpSpreadsheet/Shared/Xls.php index e25394bc..177779f8 100644 --- a/src/PhpSpreadsheet/Shared/Xls.php +++ b/src/PhpSpreadsheet/Shared/Xls.php @@ -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; diff --git a/src/PhpSpreadsheet/Style/Style.php b/src/PhpSpreadsheet/Style/Style.php index fa49a2e1..549303e3 100644 --- a/src/PhpSpreadsheet/Style/Style.php +++ b/src/PhpSpreadsheet/Style/Style.php @@ -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]) { diff --git a/src/PhpSpreadsheet/Worksheet/AutoFilter.php b/src/PhpSpreadsheet/Worksheet/AutoFilter.php index 515e3781..cb0e2e29 100644 --- a/src/PhpSpreadsheet/Worksheet/AutoFilter.php +++ b/src/PhpSpreadsheet/Worksheet/AutoFilter.php @@ -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); } diff --git a/src/PhpSpreadsheet/Worksheet/CellIterator.php b/src/PhpSpreadsheet/Worksheet/CellIterator.php index ef2ca89d..d97e33f7 100644 --- a/src/PhpSpreadsheet/Worksheet/CellIterator.php +++ b/src/PhpSpreadsheet/Worksheet/CellIterator.php @@ -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); } /** diff --git a/src/PhpSpreadsheet/Worksheet/ColumnCellIterator.php b/src/PhpSpreadsheet/Worksheet/ColumnCellIterator.php index b1d505fd..76ca596d 100644 --- a/src/PhpSpreadsheet/Worksheet/ColumnCellIterator.php +++ b/src/PhpSpreadsheet/Worksheet/ColumnCellIterator.php @@ -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; } diff --git a/src/PhpSpreadsheet/Worksheet/ColumnIterator.php b/src/PhpSpreadsheet/Worksheet/ColumnIterator.php index caee73f7..6fdfe3ba 100644 --- a/src/PhpSpreadsheet/Worksheet/ColumnIterator.php +++ b/src/PhpSpreadsheet/Worksheet/ColumnIterator.php @@ -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; } } diff --git a/src/PhpSpreadsheet/Worksheet/PageSetup.php b/src/PhpSpreadsheet/Worksheet/PageSetup.php index 175a8c11..ab007f61 100644 --- a/src/PhpSpreadsheet/Worksheet/PageSetup.php +++ b/src/PhpSpreadsheet/Worksheet/PageSetup.php @@ -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 all 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. diff --git a/src/PhpSpreadsheet/Worksheet/RowCellIterator.php b/src/PhpSpreadsheet/Worksheet/RowCellIterator.php index 99fabc6a..b839a3c4 100644 --- a/src/PhpSpreadsheet/Worksheet/RowCellIterator.php +++ b/src/PhpSpreadsheet/Worksheet/RowCellIterator.php @@ -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'); } } diff --git a/src/PhpSpreadsheet/Worksheet/Worksheet.php b/src/PhpSpreadsheet/Worksheet/Worksheet.php index 0e5fd0d6..04277a7f 100644 --- a/src/PhpSpreadsheet/Worksheet/Worksheet.php +++ b/src/PhpSpreadsheet/Worksheet/Worksheet.php @@ -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; diff --git a/src/PhpSpreadsheet/Writer/Html.php b/src/PhpSpreadsheet/Writer/Html.php index eecd9fa8..7e1a0048 100644 --- a/src/PhpSpreadsheet/Writer/Html.php +++ b/src/PhpSpreadsheet/Writer/Html.php @@ -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(); } diff --git a/src/PhpSpreadsheet/Writer/Xls.php b/src/PhpSpreadsheet/Writer/Xls.php index effa3782..6dff1342 100644 --- a/src/PhpSpreadsheet/Writer/Xls.php +++ b/src/PhpSpreadsheet/Writer/Xls.php @@ -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); diff --git a/src/PhpSpreadsheet/Writer/Xls/Worksheet.php b/src/PhpSpreadsheet/Writer/Xls/Worksheet.php index 96600169..5f374781 100644 --- a/src/PhpSpreadsheet/Writer/Xls/Worksheet.php +++ b/src/PhpSpreadsheet/Writer/Xls/Worksheet.php @@ -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); diff --git a/tests/PhpSpreadsheetTests/Cell/CoordinateTest.php b/tests/PhpSpreadsheetTests/Cell/CoordinateTest.php index 41235f6d..e6efa88e 100644 --- a/tests/PhpSpreadsheetTests/Cell/CoordinateTest.php +++ b/tests/PhpSpreadsheetTests/Cell/CoordinateTest.php @@ -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() diff --git a/tests/PhpSpreadsheetTests/Helper/SampleTest.php b/tests/PhpSpreadsheetTests/Helper/SampleTest.php index 09d6e5c2..2f87d058 100644 --- a/tests/PhpSpreadsheetTests/Helper/SampleTest.php +++ b/tests/PhpSpreadsheetTests/Helper/SampleTest.php @@ -1,6 +1,6 @@
' . - $worksheet->getCellByColumnAndRow($col, $row) - ->getValue() . - '' . $value . '