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
- Use the exact keys: 'Xlsx', 'Xls', 'Xml', 'Ods', 'Slk', 'Gnumeric', 'Html', 'Csv'
- Map old names: 'Excel2007' -> 'Xlsx', 'Excel5' -> 'Xls', 'OOCalc' -> 'Ods', 'Sylk' -> 'Slk'
- 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
- Use the exact short names; note the registry key is 'Slk', not 'Sylk'
- Test reader-type mappings in CI whenever the library is upgraded
- Prefer instantiating concrete readers (new Reader\Xlsx()) in code paths that always know the format
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
- No writer found for type $writerType
- Unable to identify a reader for this file
- Registered readers must implement PhpOffice\PhpSpreadsheet\R
- Cannot load invalid XML ${fileOrString}: ${filename}
- Registered writers must implement PhpOffice\PhpSpreadsheet\W
AI-assisted analysis of PHPOffice/PhpSpreadsheet@65b080eef4 (2026-08-17).
Data as JSON: /api/errors/67ac956ce07bfeb0.
Report an issue: GitHub.