PHPOffice/PhpSpreadsheet · error · PhpOffice\PhpSpreadsheet\Exception

Invalid Worksheet for specified Range

Error message

Invalid Worksheet for specified Range

What it means

Style::applyFromArray()/getStyle() accepts range strings that may carry a worksheet prefix such as 'Summary!A1:C10'. After uppercasing and stripping quotes, the prefixed sheet title must equal the currently active sheet's title, because the Style being modified belongs to one worksheet. Any other sheet name in the prefix throws this exception.

Source

Thrown at src/PhpSpreadsheet/Style/Style.php:223

                $ranges = explode(',', $pRange);
                $sheet = $this->getActiveSheet();
                foreach ($ranges as $range) {
                    $sheet
                        ->setSelectedCells(trim($range));
                    $this->applyFromArray($styleArray, $advancedBorders);
                }
                $sheet->setSelectedCells($pRange);

                return $this;
            }

            // Uppercase coordinate and strip any Worksheet reference from the selected range
            $pRange = strtoupper($pRange);
            if (str_contains($pRange, '!')) {
                $pRangeWorksheet = StringHelper::strToUpper(substr($pRange, 0, (int) strrpos($pRange, '!')));
                $pRangeWorksheet = Worksheet::unApostrophizeTitle($pRangeWorksheet);
                if ($pRangeWorksheet !== '' && StringHelper::strToUpper($this->getActiveSheet()->getTitle()) !== $pRangeWorksheet) {
                    throw new Exception('Invalid Worksheet for specified Range');
                }
                $pRange = strtoupper(Functions::trimSheetFromCellReference($pRange));
            }

            // Is it a cell range or a single cell?
            if (!str_contains($pRange, ':')) {
                $rangeA = $pRange;
                $rangeB = $pRange;
            } else {
                [$rangeA, $rangeB] = explode(':', $pRange);
            }

            // Calculate range outer borders
            $rangeStart = Coordinate::coordinateFromString($rangeA);
            $rangeEnd = Coordinate::coordinateFromString($rangeB);
            $rangeStartIndexes = Coordinate::indexesFromString($rangeA);
            $rangeEndIndexes = Coordinate::indexesFromString($rangeB);

View on GitHub (pinned to 65b080eef4)

Solutions

  1. Get the style from the right sheet: $spreadsheet->getSheetByName('SheetB')->getStyle('A1:C10')
  2. Or activate the target sheet first: $spreadsheet->setActiveSheetIndex($spreadsheet->getIndex($sheetB))
  3. Strip the worksheet prefix from the range string before passing it

Example fix

// before
$sheetA->getStyle('SheetB!A1:B2')->applyFromArray($style);

// after
$spreadsheet->getSheetByName('SheetB')->getStyle('A1:B2')->applyFromArray($style);
Defensive patterns

Strategy: validation

Validate before calling

[$sheetName] = \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet::extractSheetTitle($range);
if ($sheetName !== null && strtoupper($sheetName) !== strtoupper($sheet->getTitle())) {
    $sheet = $spreadsheet->getSheetByName($sheetName);
    $range = substr($range, strrpos($range, '!') + 1);
}
$sheet->getStyle($range)->applyFromArray($style);

Try / catch

try {
    $sheet->getStyle($range)->applyFromArray($style);
} catch (\PhpOffice\PhpSpreadsheet\Exception $e) {
    // range pointed at another sheet: resolve it and retry on that sheet
}

Prevention

When it happens

Trigger: $sheetA->getStyle('SheetB!A1') while the active sheet is SheetA; styling a range string copied from a formula or defined name that references another sheet.

Common situations: Code that styles cells of a non-active sheet without switching sheets first; UI range pickers that return fully-qualified 'Sheet!Range' strings; template code reused across sheets.

Related errors


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