PHPOffice/PhpSpreadsheet · error · PhpOffice\PhpSpreadsheet\Exception

Sheet does not exist.

Error message

Sheet does not exist.

What it means

Spreadsheet::getIndex(Worksheet $worksheet) walks the workbook's sheet collection looking for that exact object instance (=== comparison) and returns its position. If the instance is not one of the workbook's sheets, it throws 'Sheet does not exist.' The $noThrow flag (second argument, default false) makes it return -1 instead.

Source

Thrown at src/PhpSpreadsheet/Spreadsheet.php:764

    }

    /**
     * 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) {
            return -1;
        }

        throw new Exception('Sheet does not exist.');
    }

    /**
     * Set index for sheet by sheet name.
     *
     * @param string $worksheetName Sheet name to modify index for
     * @param int $newIndexPosition New index for the sheet
     *
     * @return int New sheet index
     */
    public function setIndexByName(string $worksheetName, int $newIndexPosition): int
    {
        $oldIndex = $this->getIndex($this->getSheetByNameOrThrow($worksheetName));
        $worksheet = array_splice(
            $this->workSheetCollection,
            $oldIndex,
            1
        );

View on GitHub (pinned to 65b080eef4)

Solutions

  1. Pass true to get -1 instead of an exception: $index = $spreadsheet->getIndex($worksheet, true); then treat -1 as 'not present'.
  2. Ensure the sheet is added to that workbook first (addSheet/addExternalSheet) before asking for its index.
  3. When merging from another workbook, add the external sheet first, then call getIndex() on the returned/attached instance.
  4. Look up by title instead of instance when identity is what matters: $spreadsheet->getSheetByName($title).

Example fix

// before
$index = $workbookA->getIndex($sheetFromWorkbookB); // throws: Sheet does not exist.

// after
$added = $workbookA->addExternalSheet($sheetFromWorkbookB);
$index = $workbookA->getIndex($added);
// or non-throwing probe:
$index = $workbookA->getIndex($maybeSheet, true);
if ($index === -1) { /* not in this workbook */ }
Defensive patterns

Strategy: validation

Validate before calling

$index = $spreadsheet->getIndex($worksheet, true); // -1 instead of exception
if ($index === -1) {
    // sheet not in this workbook: add it first or pick by title
    $spreadsheet->addSheet($worksheet);
    $index = $spreadsheet->getIndex($worksheet);
}

Type guard

function worksheetBelongsTo(\PhpOffice\PhpSpreadsheet\Spreadsheet $s, \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet $w): bool
{
    return $s->getIndex($w, true) !== -1;
}

Try / catch

try {
    $index = $spreadsheet->getIndex($worksheet);
} catch (\PhpOffice\PhpSpreadsheet\Exception $e) {
    $index = $spreadsheet->getIndex($spreadsheet->getSheetByName($worksheet->getTitle()) ?? $spreadsheet->getSheet(0));
}

Prevention

When it happens

Trigger: Passing a Worksheet that belongs to a different Spreadsheet instance (e.g. built against another workbook before addExternalSheet()); passing a clone or a freshly constructed sheet that was never added; calling getIndex() on a sheet after removeSheetByIndex() removed it.

Common situations: Merging workbooks: taking $otherSheet from workbook B and asking workbook A for its index before/without re-parenting; helper functions that accept a Worksheet and assume it lives in the spreadsheet they also receive; code that copies sheets via clone and loses track of which workbook owns what.

Related errors


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