PHPOffice/PhpSpreadsheet · error · PhpOffice\PhpSpreadsheet\Reader\Exception

$filename is an Invalid Spreadsheet file.

Error message

$filename is an Invalid Spreadsheet file.

What it means

listWorksheetInfo() performs the same canRead() signature check as the other Xml entry points; missing XML declaration or missing Office spreadssheet namespace makes the reader refuse the file before parsing sheet metadata.

Source

Thrown at src/PhpSpreadsheet/Reader/Xml.php:189

        $xml_ss = $xml->children(self::NAMESPACES_SS);
        foreach ($xml_ss->Worksheet as $worksheet) {
            $worksheet_ss = self::getAttributes($worksheet, self::NAMESPACES_SS);
            $worksheetNames[] = (string) $worksheet_ss['Name'];
        }

        return $worksheetNames;
    }

    /**
     * Return worksheet info (Name, Last Column Letter, Last Column Index, Total Rows, Total Columns).
     *
     * @return array<int, array{worksheetName: string, lastColumnLetter: string, lastColumnIndex: int, totalRows: int, totalColumns: int, sheetState: string}>
     */
    public function listWorksheetInfo(string $filename): array
    {
        File::assertFile($filename);
        if (!$this->canRead($filename)) {
            throw new Exception($filename . ' is an Invalid Spreadsheet file.');
        }

        $worksheetInfo = [];

        $xml = $this->trySimpleXMLLoadStringPrivate($filename);
        if ($xml === false) {
            throw new Exception("Problem reading {$filename}");
        }

        $worksheetID = 1;
        $xml_ss = $xml->children(self::NAMESPACES_SS);
        foreach ($xml_ss->Worksheet as $worksheet) {
            $worksheet_ss = self::getAttributes($worksheet, self::NAMESPACES_SS);

            $tmpInfo = [];
            $tmpInfo['worksheetName'] = '';
            $tmpInfo['lastColumnLetter'] = 'A';
            $tmpInfo['lastColumnIndex'] = 0;

View on GitHub (pinned to 65b080eef4)

Solutions

  1. Branch on IOFactory::identify() and only call listWorksheetInfo() when the type is 'Xml'
  2. Pre-check with canRead() and reject early with a clear message
  3. Convert genuine Excel files to SpreadsheetML or use the Xls/Xlsx readers

Example fix

// before
$info = (new \PhpOffice\PhpSpreadsheet\Reader\Xml())->listWorksheetInfo('data.xls');

// after
$reader = new \PhpOffice\PhpSpreadsheet\Reader\Xml();
if (!$reader->canRead('data.xls')) {
    throw new RuntimeException('Please upload an Excel 2003 XML Spreadsheet');
}
$info = $reader->listWorksheetInfo('data.xls');
Defensive patterns

Strategy: validation

Validate before calling

$reader = new \PhpOffice\PhpSpreadsheet\Reader\Xml();
if (!$reader->canRead($path)) {
    throw new InvalidArgumentException('Unsupported format; SpreadsheetML required');
}
$info = $reader->listWorksheetInfo($path);

Type guard

function isSpreadsheetMl(string $path): bool
{
    return (new \PhpOffice\PhpSpreadsheet\Reader\Xml())->canRead($path);
}

Prevention

When it happens

Trigger: Passing a non-SpreadsheetML file (binary .xls, .xlsx zip, generic XML, HTML) to the Xml reader's listWorksheetInfo(); files whose namespace prefix differs (no xmlns:ss binding).

Common situations: Format-detection skipped in favor of a hardcoded reader; uploads whose extension does not match content; XML from non-Microsoft tools lacking the Office namespace.

Related errors


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