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

No reader found for type $readerType

Error message

No reader found for type $readerType

What it means

IOFactory::createReader() mirrors the writer factory: the type string must be one of the registered short names ('Xlsx', 'Xls', 'Xml', 'Ods', 'Slk', 'Gnumeric', 'Html', 'Csv' plus registered readers) or a full reader class-string, matched case-sensitively. Anything else throws before the reader is instantiated. An optional $mergeArray overrides the registry for the lookup.

Source

Thrown at src/PhpSpreadsheet/IOFactory.php:117

        }

        return new $className($spreadsheet);
    }

    /**
     * Create IReader.
     *
     * @param array<string, class-string<IReader>> $mergeArray
     *        Array to use to find reader, self::$readers will be used if $readers is empty.
     */
    public static function createReader(string $readerType, array $mergeArray = []): IReader
    {
        /** @var class-string<IReader> */
        $className = $readerType;
        $readers = empty($mergeArray) ? self::$readers : $mergeArray;
        if (!in_array($readerType, $readers, true)) {
            if (!isset($readers[$readerType])) {
                throw new Reader\Exception("No reader found for type $readerType");
            }

            // Instantiate reader
            $className = $readers[$readerType];
        }

        return new $className();
    }

    /**
     * Loads Spreadsheet from file using automatic Reader\IReader resolution.
     *
     * @param string $filename The name of the spreadsheet file
     * @param int $flags the optional second parameter flags may be used to identify specific elements
     *                       that should be loaded, but which won't be loaded by default, using these values:
     *                            IReader::LOAD_WITH_CHARTS - Include any charts that are defined in the loaded file.
     *                            IReader::READ_DATA_ONLY - Read cell values only, not formatting or merge structure.
     *                            IReader::IGNORE_EMPTY_CELLS - Don't load empty cells into the model.

View on GitHub (pinned to 65b080eef4)

Solutions

  1. Use the exact keys: 'Xlsx', 'Xls', 'Xml', 'Ods', 'Slk', 'Gnumeric', 'Html', 'Csv'
  2. Map old names: 'Excel2007' -> 'Xlsx', 'Excel5' -> 'Xls', 'OOCalc' -> 'Ods', 'Sylk' -> 'Slk'
  3. Pass a class-string like \PhpOffice\PhpSpreadsheet\Reader\Xlsx::class to bypass short-name lookup

Example fix

// before
$reader = IOFactory::createReader('Excel5');

// after
$reader = IOFactory::createReader('Xls');
Defensive patterns

Strategy: validation

Validate before calling

const KNOWN_READERS = ['Xlsx', 'Xls', 'Xml', 'Ods', 'Slk', 'Gnumeric', 'Html', 'Csv'];

/** Normalize arbitrary input (extension, PHPExcel-era name) to a valid reader type. */
function normalizeReaderType(string $type): string
{
    $aliases = [
        'excel2007' => 'Xlsx', 'excel5' => 'Xls', 'oocalc' => 'Ods',
        'sylk' => 'Slk', 'excel2003xml' => 'Xml',
    ];
    $type = $aliases[strtolower(trim($type))] ?? ucfirst(strtolower(trim($type)));
    if (!in_array($type, KNOWN_READERS, true)
        && !is_a($type, \PhpOffice\PhpSpreadsheet\Reader\IReader::class, true)) {
        throw new InvalidArgumentException("Unknown reader type: $type");
    }

    return $type;
}

$reader = IOFactory::createReader(normalizeReaderType($userType));

Prevention

When it happens

Trigger: IOFactory::createReader('xlsx') lowercase; 'Excel5'/'Excel2007'/'OOCalc'/'Excel2003XML' (PHPExcel-era names); 'Sylk' instead of the registered key 'Slk'.

Common situations: Mapping file extensions to reader types without normalization; migrating legacy PHPExcel code; typos in configuration arrays that name readers.

Related errors


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