Skip to content

Commit ea58430

Browse files
author
MarkBaker
committed
Modify Autosize calculation to make allowance for the filter dropdown icon in the first row of an AutoFilter range
1 parent 9545b7a commit ea58430

File tree

3 files changed

+46
-11
lines changed

3 files changed

+46
-11
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ and this project adheres to [Semantic Versioning](https://semver.org).
6767

6868
### Fixed
6969

70+
- 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)
7071
- 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)
7172
- 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)
7273
- Allow `INDIRECT()` to accept row/column ranges as well as cell ranges [PR #2687](https://github.com/PHPOffice/PhpSpreadsheet/pull/2687)

src/PhpSpreadsheet/Shared/Font.php

+21-7
Original file line numberDiff line numberDiff line change
@@ -222,11 +222,15 @@ public static function getTrueTypeFontPath()
222222
* @param RichText|string $cellText Text to calculate width
223223
* @param int $rotation Rotation angle
224224
* @param null|FontStyle $defaultFont Font object
225-
*
226-
* @return int Column width
225+
* @param bool $filterAdjustment Add space for Autofilter or Table dropdown
227226
*/
228-
public static function calculateColumnWidth(FontStyle $font, $cellText = '', $rotation = 0, ?FontStyle $defaultFont = null)
229-
{
227+
public static function calculateColumnWidth(
228+
FontStyle $font,
229+
$cellText = '',
230+
$rotation = 0,
231+
?FontStyle $defaultFont = null,
232+
bool $filterAdjustment = false
233+
): int {
230234
// If it is rich text, use plain text
231235
if ($cellText instanceof RichText) {
232236
$cellText = $cellText->getPlainText();
@@ -237,7 +241,7 @@ public static function calculateColumnWidth(FontStyle $font, $cellText = '', $ro
237241
$lineTexts = explode("\n", $cellText);
238242
$lineWidths = [];
239243
foreach ($lineTexts as $lineText) {
240-
$lineWidths[] = self::calculateColumnWidth($font, $lineText, $rotation = 0, $defaultFont);
244+
$lineWidths[] = self::calculateColumnWidth($font, $lineText, $rotation = 0, $defaultFont, $filterAdjustment);
241245
}
242246

243247
return max($lineWidths); // width of longest line in cell
@@ -247,7 +251,13 @@ public static function calculateColumnWidth(FontStyle $font, $cellText = '', $ro
247251
$approximate = self::$autoSizeMethod == self::AUTOSIZE_METHOD_APPROX;
248252
$columnWidth = 0;
249253
if (!$approximate) {
250-
$columnWidthAdjust = ceil(self::getTextWidthPixelsExact('n', $font, 0) * 1.07);
254+
$columnWidthAdjust = ceil(
255+
self::getTextWidthPixelsExact(
256+
str_repeat('n', 1 * ($filterAdjustment ? 3 : 1)),
257+
$font,
258+
0
259+
) * 1.07
260+
);
251261

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

261271
if ($approximate) {
262-
$columnWidthAdjust = self::getTextWidthPixelsApprox('n', $font, 0);
272+
$columnWidthAdjust = self::getTextWidthPixelsApprox(
273+
str_repeat('n', 1 * ($filterAdjustment ? 3 : 1)),
274+
$font,
275+
0
276+
);
263277
// Width of text in pixels excl. padding, approximation
264278
// and addition because Excel adds some padding, just use approx width of 'n' glyph
265279
$columnWidth = self::getTextWidthPixelsApprox($cellText, $font, $rotation) + $columnWidthAdjust;

src/PhpSpreadsheet/Worksheet/Worksheet.php

+24-4
Original file line numberDiff line numberDiff line change
@@ -733,9 +733,19 @@ public function calculateColumnWidths()
733733
}
734734
}
735735

736+
$autoFilterRange = $autoFilterFirstRowRange = $this->autoFilter->getRange();
737+
if (!empty($autoFilterRange)) {
738+
$autoFilterRangeBoundaries = Coordinate::rangeBoundaries($autoFilterRange);
739+
$autoFilterFirstRowRange = (string) new CellRange(
740+
CellAddress::fromColumnAndRow($autoFilterRangeBoundaries[0][0], $autoFilterRangeBoundaries[0][1]),
741+
CellAddress::fromColumnAndRow($autoFilterRangeBoundaries[1][0], $autoFilterRangeBoundaries[0][1])
742+
);
743+
}
744+
736745
// loop through all cells in the worksheet
737746
foreach ($this->getCoordinates(false) as $coordinate) {
738747
$cell = $this->getCellOrNull($coordinate);
748+
739749
if ($cell !== null && isset($autoSizes[$this->cellCollection->getCurrentColumn()])) {
740750
//Determine if cell is in merge range
741751
$isMerged = isset($isMergeCell[$this->cellCollection->getCurrentCoordinate()]);
@@ -752,13 +762,21 @@ public function calculateColumnWidths()
752762
}
753763
}
754764

755-
// Determine width if cell does not participate in a merge or does and is a value cell of 1-column wide range
765+
// Determine width if cell is not part of a merge or does and is a value cell of 1-column wide range
756766
if (!$isMerged || $isMergedButProceed) {
767+
// Determine if we need to make an adjustment for the first row in an AutoFilter range that
768+
// has a column filter dropdown
769+
$filterAdjustment = false;
770+
if (!empty($autoFilterRange) && $cell->isInRange($autoFilterFirstRowRange)) {
771+
$filterAdjustment = true;
772+
}
773+
757774
// Calculated value
758775
// To formatted string
759776
$cellValue = NumberFormat::toFormattedString(
760777
$cell->getCalculatedValue(),
761-
$this->getParent()->getCellXfByIndex($cell->getXfIndex())->getNumberFormat()->getFormatCode()
778+
$this->getParent()->getCellXfByIndex($cell->getXfIndex())
779+
->getNumberFormat()->getFormatCode()
762780
);
763781

764782
if ($cellValue !== null && $cellValue !== '') {
@@ -767,8 +785,10 @@ public function calculateColumnWidths()
767785
(float) Shared\Font::calculateColumnWidth(
768786
$this->getParent()->getCellXfByIndex($cell->getXfIndex())->getFont(),
769787
$cellValue,
770-
$this->getParent()->getCellXfByIndex($cell->getXfIndex())->getAlignment()->getTextRotation(),
771-
$this->getParent()->getDefaultStyle()->getFont()
788+
$this->getParent()->getCellXfByIndex($cell->getXfIndex())
789+
->getAlignment()->getTextRotation(),
790+
$this->getParent()->getDefaultStyle()->getFont(),
791+
$filterAdjustment
772792
)
773793
);
774794
}

0 commit comments

Comments
 (0)