PHPOffice/PhpSpreadsheet · error · PhpOffice\PhpSpreadsheet\Exception

Sheet {$worksheetName} does not exist.

Error message

Sheet {$worksheetName} does not exist.

What it means

Spreadsheet::getSheetByNameOrThrow() is the throwing variant of getSheetByName(): it looks a worksheet up by title and throws when the workbook has no sheet with that name (the non-throwing twin returns null). Lookup is case-insensitive on title, but the name must otherwise match exactly, including any whitespace.

Source

Thrown at src/PhpSpreadsheet/Spreadsheet.php:742

    {
        $trimWorksheetName = StringHelper::strToUpper(trim($worksheetName, "'"));
        foreach ($this->workSheetCollection as $worksheet) {
            if (StringHelper::strToUpper($worksheet->getTitle()) === $trimWorksheetName) {
                return $worksheet;
            }
        }

        return null;
    }

    /**
     * Get sheet by name, throwing exception if not found.
     */
    public function getSheetByNameOrThrow(string $worksheetName): Worksheet
    {
        $worksheet = $this->getSheetByName($worksheetName);
        if ($worksheet === null) {
            throw new Exception("Sheet $worksheetName does not exist.");
        }

        return $worksheet;
    }

    /**
     * Get index for sheet.
     *
     * @return int index
     */
    public function getIndex(Worksheet $worksheet, bool $noThrow = false): int
    {
        foreach ($this->workSheetCollection as $key => $value) {
            if ($value === $worksheet) {
                return $key;
            }
        }
        if ($noThrow) {

View on GitHub (pinned to 65b080eef4)

Solutions

  1. List what actually exists: var_export($spreadsheet->getSheetNames()); and compare the exact strings (use var_dump to reveal whitespace).
  2. Check first with $spreadsheet->sheetNameExists($name) (case-insensitive) before the throwing call.
  3. trim() and normalize user-supplied names before lookup.
  4. If absence is expected, use the non-throwing $spreadsheet->getSheetByName($name) and handle null yourself.

Example fix

// before
$sheet = $spreadsheet->getSheetByNameOrThrow('Summary'); // throws

// after
$name = trim($request->get('sheet'));
$sheet = $spreadsheet->getSheetByName($name)
    ?? $spreadsheet->getSheetByNameOrThrow($spreadsheet->getSheetNames()[0]);
Defensive patterns

Strategy: validation

Validate before calling

$name = trim($name);
if (!$spreadsheet->sheetNameExists($name)) {
    throw new \InvalidArgumentException("Unknown sheet '$name'. Available: " . implode(', ', $spreadsheet->getSheetNames()));
}
$sheet = $spreadsheet->getSheetByNameOrThrow($name);

Type guard

function sheetNameIsKnown(\PhpOffice\PhpSpreadsheet\Spreadsheet $s, string $name): bool
{
    return $s->sheetNameExists(trim($name));
}

Try / catch

try {
    $sheet = $spreadsheet->getSheetByNameOrThrow($name);
} catch (\PhpOffice\PhpSpreadsheet\Exception $e) {
    // fall back to first tab, or surface available names to the caller
    $sheet = $spreadsheet->getSheet(0);
}

Prevention

When it happens

Trigger: getSheetByNameOrThrow('Summary') when the sheet is titled 'Summary ' (trailing space), 'SUMMARY report', or was renamed by earlier code; reading a fixed name like 'Sheet1' from a file whose tabs were renamed; names built from user input or column values with hidden characters (newline, non-breaking space).

Common situations: Hard-coded sheet names versus user-maintained spreadsheets; names assembled dynamically (e.g. "Week {$week}") where the computed string does not match the tab; files where Excel stored the title with surrounding whitespace; locale/case differences after a file round-trip.

Related errors


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