Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

improved performance of column width calculation for spreadsheets wit… #1628

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 23 additions & 10 deletions src/PhpSpreadsheet/Cell/Cell.php
Original file line number Diff line number Diff line change
Expand Up @@ -496,16 +496,27 @@ public function isInMergeRange()
public function isMergeRangeValueCell()
{
if ($mergeRange = $this->getMergeRange()) {
$mergeRange = Coordinate::splitRange($mergeRange);
[$startCell] = $mergeRange[0];
if ($this->getCoordinate() === $startCell) {
return true;
}
return $this->isMergeRangeValueCell2($mergeRange);
}

return false;
}

/**
* Is this cell the master (top left cell) in a merge range (that holds the actual data value).
*
* @param string $mergeRange merge range from getMergeRange()
*
* @return bool
*/
public function isMergeRangeValueCell2($mergeRange)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All new methods must declare their typing

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Idea for perhaps better name: isFirstInMergedRange

{
$splittedRanges = Coordinate::splitRange($mergeRange);
[$startCell] = $splittedRanges[0];

return $this->getCoordinate() === $startCell;
}

/**
* If this cell is in a merge range, then return the range.
*
Expand Down Expand Up @@ -555,13 +566,15 @@ public function isInRange($pRange)
{
[$rangeStart, $rangeEnd] = Coordinate::rangeBoundaries($pRange);

// Translate properties
$myColumn = Coordinate::columnIndexFromString($this->getColumn());
// Verify if cell is in range
$myRow = $this->getRow();
if ($rangeStart[1] <= $myRow && $rangeEnd[1] >= $myRow) {
$myColumn = Coordinate::columnIndexFromString($this->getColumn());

// Verify if cell is in range
return ($rangeStart[0] <= $myColumn) && ($rangeEnd[0] >= $myColumn) &&
($rangeStart[1] <= $myRow) && ($rangeEnd[1] >= $myRow);
return ($rangeStart[0] <= $myColumn) && ($rangeEnd[0] >= $myColumn);
}

return false;
}

/**
Expand Down
15 changes: 14 additions & 1 deletion src/PhpSpreadsheet/Cell/Coordinate.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,13 @@
*/
abstract class Coordinate
{
/**
* Cache for rangeBoundaries.
*
* @var array
*/
private static $_rangeBoundariesCache = [];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using underscore in variable name is almost never used in this project.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. We're trying to move away from underscore usage. So new usage should not be added again.


/**
* Default range variable constant.
*
Expand Down Expand Up @@ -167,6 +174,10 @@ public static function buildRange(array $pRange)
*/
public static function rangeBoundaries($pRange)
{
if (isset(self::$_rangeBoundariesCache[$pRange])) {
return self::$_rangeBoundariesCache[$pRange];
}

// Ensure $pRange is a valid range
if (empty($pRange)) {
$pRange = self::DEFAULT_RANGE;
Expand All @@ -184,12 +195,14 @@ public static function rangeBoundaries($pRange)

// Calculate range outer borders
$rangeStart = self::coordinateFromString($rangeA);
$rangeEnd = self::coordinateFromString($rangeB);
$rangeEnd = $rangeA === $rangeB ? $rangeStart : self::coordinateFromString($rangeB);

// Translate column into index
$rangeStart[0] = self::columnIndexFromString($rangeStart[0]);
$rangeEnd[0] = self::columnIndexFromString($rangeEnd[0]);

self::$_rangeBoundariesCache[$pRange] = [$rangeStart, $rangeEnd];

return [$rangeStart, $rangeEnd];
}

Expand Down
10 changes: 6 additions & 4 deletions src/PhpSpreadsheet/Worksheet/Worksheet.php
Original file line number Diff line number Diff line change
Expand Up @@ -737,11 +737,13 @@ public function calculateColumnWidths()
$isMergedButProceed = false;

//The only exception is if it's a merge range value cell of a 'vertical' randge (1 column wide)
if ($isMerged && $cell->isMergeRangeValueCell()) {
if ($isMerged) {
$range = $cell->getMergeRange();
$rangeBoundaries = Coordinate::rangeDimension($range);
if ($rangeBoundaries[0] == 1) {
$isMergedButProceed = true;
if ($cell->isMergeRangeValueCell2($range)) {
$rangeBoundaries = Coordinate::rangeDimension($range);
if ($rangeBoundaries[0] == 1) {
$isMergedButProceed = true;
}
}
}

Expand Down