Skip to content
Merged
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
17 changes: 7 additions & 10 deletions src/PhpSpreadsheet/Shared/Font.php
Original file line number Diff line number Diff line change
Expand Up @@ -453,29 +453,26 @@ public static function getTextWidthPixelsApprox($columnText, FontStyle $font, $r
$fontName = $font->getName();
$fontSize = $font->getSize();

// Calculate column width in pixels. We assume fixed glyph width. Result varies with font name and size.
// Calculate column width in pixels.
// We assume fixed glyph width, but count double for "fullwidth" characters.
// Result varies with font name and size.
switch ($fontName) {
case 'Calibri':
// value 8.26 was found via interpolation by inspecting real Excel files with Calibri 11 font.
$columnWidth = (int) (8.26 * StringHelper::countCharacters($columnText));
$columnWidth = $columnWidth * $fontSize / 11; // extrapolate from font size

break;
case 'Arial':
// value 8 was set because of experience in different exports at Arial 10 font.
$columnWidth = (int) (8 * StringHelper::countCharacters($columnText));
$columnWidth = (int) (8 * StringHelper::countCharactersDbcs($columnText));
$columnWidth = $columnWidth * $fontSize / 10; // extrapolate from font size

break;
case 'Verdana':
// value 8 was found via interpolation by inspecting real Excel files with Verdana 10 font.
$columnWidth = (int) (8 * StringHelper::countCharacters($columnText));
$columnWidth = (int) (8 * StringHelper::countCharactersDbcs($columnText));
$columnWidth = $columnWidth * $fontSize / 10; // extrapolate from font size

break;
default:
// just assume Calibri
$columnWidth = (int) (8.26 * StringHelper::countCharacters($columnText));
// value 8.26 was found via interpolation by inspecting real Excel files with Calibri 11 font.
$columnWidth = (int) (8.26 * StringHelper::countCharactersDbcs($columnText));
$columnWidth = $columnWidth * $fontSize / 11; // extrapolate from font size

break;
Expand Down
12 changes: 12 additions & 0 deletions src/PhpSpreadsheet/Shared/StringHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,18 @@ public static function countCharacters(string $textValue, string $encoding = 'UT
return mb_strlen($textValue, $encoding);
}

/**
* Get character count using mb_strwidth rather than mb_strlen.
*
* @param string $encoding Encoding
*
* @return int Character count
*/
public static function countCharactersDbcs(string $textValue, string $encoding = 'UTF-8'): int
{
return mb_strwidth($textValue, $encoding);
}

/**
* Get a substring of a UTF-8 encoded string.
*
Expand Down
2 changes: 2 additions & 0 deletions tests/PhpSpreadsheetTests/Shared/FontTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,8 @@ public function providerCalculateApproximateColumnWidth(): array
[9.2834, new StyleFont(), "Hello\nWorld", 0, new StyleFont(), true, 0],
[17.5671, new StyleFont(), 'PhpSpreadsheet', 0, new StyleFont(), false, 0],
[19.8523, new StyleFont(), 'PhpSpreadsheet', 0, new StyleFont(), false, 1],
'CJK characters width must be >= 43.00' => [55.2722, new StyleFont(), '如果某一列是CJK 其中的一种,这样的设置方式无效', 0, new StyleFont(), false, 0],
'non-CJK characters width must be >= 24.73' => [31.7065, new StyleFont(), 'abcdefghijklmnopqrstuvwxyz', 0, new StyleFont(), false, 0],
];
}
}