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

{filename} is an Invalid SYLK file.

Error message

{filename} is an Invalid SYLK file.

What it means

The SYLK (.slk) reader's canReadOrBust() requires the format's signature: a first record starting with ID;P plus recognizable delimiter lines. When canRead() fails it throws 'Invalid SYLK file' before parsing, so the content simply is not a Multiplan-style SYLK export.

Source

Thrown at src/PhpSpreadsheet/Reader/Slk.php:84

        $data = (string) fread($this->fileHandle, 2048);

        // Count delimiters in file
        $delimiterCount = substr_count($data, ';');
        $hasDelimiter = $delimiterCount > 0;

        // Analyze first line looking for ID; signature
        $lines = explode("\n", $data);
        $hasId = str_starts_with($lines[0], 'ID;P');

        fclose($this->fileHandle);

        return $hasDelimiter && $hasId;
    }

    private function canReadOrBust(string $filename): void
    {
        if (!$this->canRead($filename)) {
            throw new ReaderException($filename . ' is an Invalid SYLK file.');
        }
        $this->openFile($filename);
    }

    /**
     * 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
    {
        // Open file
        $this->canReadOrBust($filename);
        $fileHandle = $this->fileHandle;
        rewind($fileHandle);

        $worksheetInfo = [['worksheetName' => basename($filename, '.slk')]];

View on GitHub (pinned to 65b080eef4)

Solutions

  1. Use IOFactory::identify() to route the file to the right reader
  2. Open the file in Excel/LibreOffice and re-export as genuine SYLK (or better, CSV/xlsx)
  3. Sanity-check the first line: it should start with ID;P before you attempt the Slk reader

Example fix

// before
$spreadsheet = (new Slk())->load('export.slk'); // first line is not ID;P -> throws

// after
$first = (string) fgets(fopen($uploadPath, 'rb'));
if (!str_starts_with($first, 'ID;P')) {
    $reader = IOFactory::createReader(IOFactory::identify($uploadPath));
    $spreadsheet = $reader->load($uploadPath);
} else {
    $spreadsheet = (new Slk())->load($uploadPath);
}
Defensive patterns

Strategy: validation

Validate before calling

$firstLine = (string) fgets(fopen($filename, 'rb'));
if (!str_starts_with($firstLine, 'ID;P')) {
    throw new RuntimeException('File lacks the SYLK ID;P signature');
}
$spreadsheet = (new Slk())->load($filename);

Prevention

When it happens

Trigger: A .slk file whose first line is not ID;P (some tools emit data records or a preamble first); a plain text file renamed .slk; a SYLK variant using line endings/escapes the sniff does not recognize.

Common situations: Exports from niche ERP/lab tools that produce 'almost-SYLK' text; legacy .slk archives; user uploads validated by extension only.

Related errors


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