PHPOffice/PhpSpreadsheet · error · PhpOffice\PhpSpreadsheet\Exception

Unknown font name "$name". Cannot map to TrueType font file

Error message

Unknown font name "$name". Cannot map to TrueType font file

What it means

Thrown by Font::getTrueTypeFontFileFromFont() when the font's name does not appear in the built-in FONT_FILE_NAMES map nor in the extra array registered via Font::setExtraFontArray(). The library can only compute exact text widths for fonts it can map to a .ttf file, so an unregistered name is fatal for the 'exact' auto-size path.

Source

Thrown at src/PhpSpreadsheet/Shared/Font.php:550

    {
        return $sizeInCm * 37.795275591;
    }

    /**
     * Returns the font path given the font.
     *
     * @return string Path to TrueType font file
     */
    public static function getTrueTypeFontFileFromFont(FontStyle $font, bool $checkPath = true): string
    {
        if ($checkPath && (!file_exists(self::$trueTypeFontPath) || !is_dir(self::$trueTypeFontPath))) {
            throw new PhpSpreadsheetException('Valid directory to TrueType Font files not specified');
        }

        $name = $font->getName();
        $fontArray = array_merge(self::FONT_FILE_NAMES, self::$extraFontArray);
        if (!isset($fontArray[$name])) {
            throw new PhpSpreadsheetException('Unknown font name "' . $name . '". Cannot map to TrueType font file');
        }
        $bold = $font->getBold();
        $italic = $font->getItalic();
        $index = 'x';
        if ($bold) {
            $index .= 'b';
        }
        if ($italic) {
            $index .= 'i';
        }
        $fontFile = $fontArray[$name][$index];

        $separator = '';
        if (mb_strlen(self::$trueTypeFontPath) > 1 && mb_substr(self::$trueTypeFontPath, -1) !== '/' && mb_substr(self::$trueTypeFontPath, -1) !== '\\') {
            $separator = DIRECTORY_SEPARATOR;
        }
        $fontFileAbsolute = preg_match('~^([A-Za-z]:)?[/\\\]~', $fontFile) === 1;
        if (!$fontFileAbsolute) {

View on GitHub (pinned to 65b080eef4)

Solutions

  1. Register the font before saving: Font::setExtraFontArray(['Roboto' => ['xb' => 'Roboto-Regular.ttf', 'xbi' => 'Roboto-BoldItalic.ttf', 'xi' => 'Roboto-Italic.ttf', 'x' => 'Roboto-Bold.ttf']]) in the documented shape, with the files present in Font::getTrueTypeFontPath().
  2. Prefer one of the well-known mapped names (Calibri, Arial, Times New Roman, Courier New, ...) for the fonts used in auto-sized columns.
  3. Normalize the name you set (trim, exact casing) and check membership before saving: in_array($name, array_keys(array_merge(Font::FONT_FILE_NAMES, Font::getExtraFontArray())), true).
  4. If exact mapping is impossible, fall back to Font::setAutoSizeMethod(Font::AUTOSIZE_METHOD_APPROX).

Example fix

// before
$sheet->getStyle('A1')->getFont()->setName('Roboto');
Font::setAutoSizeMethod(Font::AUTOSIZE_METHOD_EXACT);
$writer->save('out.xlsx'); // Unknown font name "Roboto"

// after
Font::setTrueTypeFontPath('/var/www/fonts');
Font::setExtraFontArray(['Roboto' => [
    'x' => 'Roboto-Regular.ttf', 'xb' => 'Roboto-Bold.ttf',
    'xi' => 'Roboto-Italic.ttf', 'xbi' => 'Roboto-BoldItalic.ttf',
]]);
$sheet->getStyle('A1')->getFont()->setName('Roboto');
Defensive patterns

Strategy: validation

Validate before calling

use PhpOffice\PhpSpreadsheet\Shared\Font;
function fontIsMeasurable(string $name): bool
{
    $known = array_merge(Font::FONT_FILE_NAMES, Font::getExtraFontArray());
    return isset($known[trim($name)]);
}
// before save:
foreach ($sheet->getStyleCollection?? [] as $_) {} // (iterate your styles as needed)
if (!fontIsMeasurable($fontName)) { /* register extra array or switch font */ }

Type guard

function measurableFontName(string $name): ?string
{
    $known = array_merge(Font::FONT_FILE_NAMES, Font::getExtraFontArray());
    return isset($known[$name]) ? $name : null; // narrow to a usable name
}

Try / catch

try { $writer->save($path); }
catch (\PhpOffice\PhpSpreadsheet\Exception $e) {
    if (str_contains($e->getMessage(), 'Unknown font name')) {
        // register the font or fall back to approx sizing, then retry
        Font::setExtraFontArray(array_merge(Font::getExtraFontArray(), $extraDefs));
        $writer->save($path);
    } else { throw $e; }
}

Prevention

When it happens

Trigger: Setting a cell/row/default font name that is not one of the known mappings (e.g. $sheet->getStyle('A1')->getFont()->setName('Roboto')) and then saving with Font::setAutoSizeMethod(Font::AUTOSIZE_METHOD_EXACT); the lookup `array_merge(self::FONT_FILE_NAMES, self::$extraFontArray)` finds no key 'Roboto' and throws. Also triggered by name case/whitespace mismatches, since the lookup is an exact isset() on the string.

Common situations: Corporate-brand fonts (Roboto, Lato, Source Sans) applied to generated reports; copying a font name with a trailing space or wrong casing from a design spec; a file loaded from a template whose theme font is unusual, then re-saved with exact auto-size enabled.

Related errors


AI-assisted analysis of PHPOffice/PhpSpreadsheet@65b080eef4 (2026-08-17). Data as JSON: /api/errors/27afe138237413dd. Report an issue: GitHub.