PHPOffice/PhpSpreadsheet · error · PhpOffice\PhpSpreadsheet\Exception

Unknown codepage: ${codepage}

Error message

Unknown codepage: ${codepage}

What it means

XlsBase::setCodepage() rejects any codepage string that CodePage::validate() does not recognize. The codepage only matters for BIFF5 (Excel 5/95) strings; BIFF8 files are always UTF-16LE internally and do not need one.

Source

Thrown at src/PhpSpreadsheet/Reader/XlsBase.php:139

        Border::BORDER_DASHDOT, // => 0x09,
        Border::BORDER_MEDIUMDASHDOT, // => 0x0A,
        Border::BORDER_DASHDOTDOT, // => 0x0B,
        Border::BORDER_MEDIUMDASHDOTDOT, // => 0x0C,
        Border::BORDER_SLANTDASHDOT, // => 0x0D,
        Border::BORDER_OMIT, // => 0x0E,
        Border::BORDER_OMIT, // => 0x0F,
    ];

    /**
     * Codepage set in the Excel file being read. Only important for BIFF5 (Excel 5.0 - Excel 95)
     * For BIFF8 (Excel 97 - Excel 2003) this will always have the value 'UTF-16LE'.
     */
    protected string $codepage = '';

    public function setCodepage(string $codepage): void
    {
        if (CodePage::validate($codepage) === false) {
            throw new PhpSpreadsheetException('Unknown codepage: ' . $codepage);
        }

        $this->codepage = $codepage;
    }

    public function getCodepage(): string
    {
        return $this->codepage;
    }

    /**
     * Can the current IReader read the file?
     */
    public function canRead(string $filename): bool
    {
        if (File::testFileNoThrow($filename) === false) {
            return false;
        }

View on GitHub (pinned to 65b080eef4)

Solutions

  1. Pass a Microsoft codepage name understood by the table, e.g. 'CP1252' (Western European), 'CP1251', 'CP932', 'CP936'
  2. Validate first with CodePage::validate($cp) before calling setCodepage
  3. If the file is BIFF8 (Excel 97-2003), do not set a codepage at all — it is ignored/unnecessary

Example fix

// before
$reader = new \PhpOffice\PhpSpreadsheet\Reader\Xls();
$reader->setCodepage('UTF-8'); // Unknown codepage: UTF-8

// after
$reader = new \PhpOffice\PhpSpreadsheet\Reader\Xls();
$cp = 'CP1252';
if (\PhpOffice\PhpSpreadsheet\Shared\CodePage::validate($cp)) {
    $reader->setCodepage($cp);
}
Defensive patterns

Strategy: validation

Validate before calling

use \PhpOffice\PhpSpreadsheet\Shared\CodePage;
$cp = 'CP1252';
if (CodePage::validate($cp)) {
    $reader->setCodepage($cp);
}

Type guard

function isKnownCodepage(string $cp): bool
{
    return \PhpOffice\PhpSpreadsheet\Shared\CodePage::validate($cp);
}

Prevention

When it happens

Trigger: Calling $reader->setCodepage('UTF-8') or another generic encoding name instead of a Microsoft codepage identifier like 'CP1252'; typos such as 'cp-1252'; passing an encoding mb_convert_encoding knows but the CodePage table does not.

Common situations: Copy-pasting an iconv/mb_list_encodings name into setCodepage; upgrading code from very old PHPExcel examples that used different codepage naming.

Related errors


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