Skip to content

Commit

Permalink
Merge pull request #2754 from PHPOffice/Issue-2413_Autosize-Column-Al…
Browse files Browse the repository at this point in the history
…low-for-AutoFilter

Modify Autosize calculation to make allowance for the filter dropdown icon in the first row of an AutoFilter range
  • Loading branch information
MarkBaker authored Apr 17, 2022
2 parents 9545b7a + ea58430 commit f426889
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 11 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ and this project adheres to [Semantic Versioning](https://semver.org).

### Fixed

- Make allowance for the AutoFilter dropdown icon in the first row of an Autofilter range when using Autosize columns. [Issue #2413](https://github.com/PHPOffice/PhpSpreadsheet/issues/2413) [PR #2754](https://github.com/PHPOffice/PhpSpreadsheet/pull/2754)
- Support for "chained" ranges (e.g. `A5:C10:C20:F1`) in the Calculation Engine; and also support for using named ranges with the Range operator (e.g. `NamedRange1:NamedRange2`) [Issue #2730](https://github.com/PHPOffice/PhpSpreadsheet/issues/2730) [PR #2746](https://github.com/PHPOffice/PhpSpreadsheet/pull/2746)
- Update Conditional Formatting ranges and rule conditions when inserting/deleting rows/columns [Issue #2678](https://github.com/PHPOffice/PhpSpreadsheet/issues/2678) [PR #2689](https://github.com/PHPOffice/PhpSpreadsheet/pull/2689)
- Allow `INDIRECT()` to accept row/column ranges as well as cell ranges [PR #2687](https://github.com/PHPOffice/PhpSpreadsheet/pull/2687)
Expand Down
28 changes: 21 additions & 7 deletions src/PhpSpreadsheet/Shared/Font.php
Original file line number Diff line number Diff line change
Expand Up @@ -222,11 +222,15 @@ public static function getTrueTypeFontPath()
* @param RichText|string $cellText Text to calculate width
* @param int $rotation Rotation angle
* @param null|FontStyle $defaultFont Font object
*
* @return int Column width
* @param bool $filterAdjustment Add space for Autofilter or Table dropdown
*/
public static function calculateColumnWidth(FontStyle $font, $cellText = '', $rotation = 0, ?FontStyle $defaultFont = null)
{
public static function calculateColumnWidth(
FontStyle $font,
$cellText = '',
$rotation = 0,
?FontStyle $defaultFont = null,
bool $filterAdjustment = false
): int {
// If it is rich text, use plain text
if ($cellText instanceof RichText) {
$cellText = $cellText->getPlainText();
Expand All @@ -237,7 +241,7 @@ public static function calculateColumnWidth(FontStyle $font, $cellText = '', $ro
$lineTexts = explode("\n", $cellText);
$lineWidths = [];
foreach ($lineTexts as $lineText) {
$lineWidths[] = self::calculateColumnWidth($font, $lineText, $rotation = 0, $defaultFont);
$lineWidths[] = self::calculateColumnWidth($font, $lineText, $rotation = 0, $defaultFont, $filterAdjustment);
}

return max($lineWidths); // width of longest line in cell
Expand All @@ -247,7 +251,13 @@ public static function calculateColumnWidth(FontStyle $font, $cellText = '', $ro
$approximate = self::$autoSizeMethod == self::AUTOSIZE_METHOD_APPROX;
$columnWidth = 0;
if (!$approximate) {
$columnWidthAdjust = ceil(self::getTextWidthPixelsExact('n', $font, 0) * 1.07);
$columnWidthAdjust = ceil(
self::getTextWidthPixelsExact(
str_repeat('n', 1 * ($filterAdjustment ? 3 : 1)),
$font,
0
) * 1.07
);

try {
// Width of text in pixels excl. padding
Expand All @@ -259,7 +269,11 @@ public static function calculateColumnWidth(FontStyle $font, $cellText = '', $ro
}

if ($approximate) {
$columnWidthAdjust = self::getTextWidthPixelsApprox('n', $font, 0);
$columnWidthAdjust = self::getTextWidthPixelsApprox(
str_repeat('n', 1 * ($filterAdjustment ? 3 : 1)),
$font,
0
);
// Width of text in pixels excl. padding, approximation
// and addition because Excel adds some padding, just use approx width of 'n' glyph
$columnWidth = self::getTextWidthPixelsApprox($cellText, $font, $rotation) + $columnWidthAdjust;
Expand Down
28 changes: 24 additions & 4 deletions src/PhpSpreadsheet/Worksheet/Worksheet.php
Original file line number Diff line number Diff line change
Expand Up @@ -733,9 +733,19 @@ public function calculateColumnWidths()
}
}

$autoFilterRange = $autoFilterFirstRowRange = $this->autoFilter->getRange();
if (!empty($autoFilterRange)) {
$autoFilterRangeBoundaries = Coordinate::rangeBoundaries($autoFilterRange);
$autoFilterFirstRowRange = (string) new CellRange(
CellAddress::fromColumnAndRow($autoFilterRangeBoundaries[0][0], $autoFilterRangeBoundaries[0][1]),
CellAddress::fromColumnAndRow($autoFilterRangeBoundaries[1][0], $autoFilterRangeBoundaries[0][1])
);
}

// loop through all cells in the worksheet
foreach ($this->getCoordinates(false) as $coordinate) {
$cell = $this->getCellOrNull($coordinate);

if ($cell !== null && isset($autoSizes[$this->cellCollection->getCurrentColumn()])) {
//Determine if cell is in merge range
$isMerged = isset($isMergeCell[$this->cellCollection->getCurrentCoordinate()]);
Expand All @@ -752,13 +762,21 @@ public function calculateColumnWidths()
}
}

// Determine width if cell does not participate in a merge or does and is a value cell of 1-column wide range
// Determine width if cell is not part of a merge or does and is a value cell of 1-column wide range
if (!$isMerged || $isMergedButProceed) {
// Determine if we need to make an adjustment for the first row in an AutoFilter range that
// has a column filter dropdown
$filterAdjustment = false;
if (!empty($autoFilterRange) && $cell->isInRange($autoFilterFirstRowRange)) {
$filterAdjustment = true;
}

// Calculated value
// To formatted string
$cellValue = NumberFormat::toFormattedString(
$cell->getCalculatedValue(),
$this->getParent()->getCellXfByIndex($cell->getXfIndex())->getNumberFormat()->getFormatCode()
$this->getParent()->getCellXfByIndex($cell->getXfIndex())
->getNumberFormat()->getFormatCode()
);

if ($cellValue !== null && $cellValue !== '') {
Expand All @@ -767,8 +785,10 @@ public function calculateColumnWidths()
(float) Shared\Font::calculateColumnWidth(
$this->getParent()->getCellXfByIndex($cell->getXfIndex())->getFont(),
$cellValue,
$this->getParent()->getCellXfByIndex($cell->getXfIndex())->getAlignment()->getTextRotation(),
$this->getParent()->getDefaultStyle()->getFont()
$this->getParent()->getCellXfByIndex($cell->getXfIndex())
->getAlignment()->getTextRotation(),
$this->getParent()->getDefaultStyle()->getFont(),
$filterAdjustment
)
);
}
Expand Down

0 comments on commit f426889

Please sign in to comment.