PHPOffice/PhpSpreadsheet · error · PhpOffice\PhpSpreadsheet\Exception

Spreadsheet objects cannot be json encoded

Error message

Spreadsheet objects cannot be json encoded

What it means

Spreadsheet implements JsonSerializable but its jsonSerialize() always throws: workbooks contain cyclic object graphs, file-backed resources and non-representable internals, so there is no meaningful JSON form. Any attempt to json_encode() a Spreadsheet instance (or an array/object graph containing one) triggers this exception by design.

Source

Thrown at src/PhpSpreadsheet/Spreadsheet.php:1728

    public function reevaluateAutoFilters(bool $resetToMax): void
    {
        foreach ($this->workSheetCollection as $sheet) {
            $filter = $sheet->getAutoFilter();
            if (!empty($filter->getRange())) {
                if ($resetToMax) {
                    $filter->setRangeToMaxRow();
                }
                $filter->showHideRows();
            }
        }
    }

    /**
     * @throws Exception
     */
    public function jsonSerialize(): mixed
    {
        throw new Exception('Spreadsheet objects cannot be json encoded');
    }

    public function resetThemeFonts(): void
    {
        $majorFontLatin = $this->theme->getMajorFontLatin();
        $minorFontLatin = $this->theme->getMinorFontLatin();
        foreach ($this->cellXfCollection as $cellStyleXf) {
            $scheme = $cellStyleXf->getFont()->getScheme();
            if ($scheme === 'major') {
                $cellStyleXf->getFont()->setName($majorFontLatin)->setScheme($scheme);
            } elseif ($scheme === 'minor') {
                $cellStyleXf->getFont()->setName($minorFontLatin)->setScheme($scheme);
            }
        }
        foreach ($this->cellStyleXfCollection as $cellStyleXf) {
            $scheme = $cellStyleXf->getFont()->getScheme();
            if ($scheme === 'major') {
                $cellStyleXf->getFont()->setName($majorFontLatin)->setScheme($scheme);

View on GitHub (pinned to 65b080eef4)

Solutions

  1. Convert to data first: $rows = $spreadsheet->getActiveSheet()->toArray(null, true, true, true); then json_encode($rows).
  2. Save to a file and return the path/URL instead of the object: IOFactory::createWriter($spreadsheet, 'Xlsx')->save($path);
  3. Extract only the fields you need (sheet names, specific cell ranges) into a plain array before encoding.
  4. Keep Spreadsheet instances out of logger context and queue payloads.

Example fix

// before
return response()->json(['spreadsheet' => $spreadsheet]); // throws

// after
$data = [
    'sheetNames' => $spreadsheet->getSheetNames(),
    'rows' => $spreadsheet->getActiveSheet()->toArray(null, true, true, true),
];
return response()->json($data);
Defensive patterns

Strategy: validation

Validate before calling

// Extract plain data before encoding
$payload = [
    'sheetNames' => $spreadsheet->getSheetNames(),
    'rows' => $spreadsheet->getActiveSheet()->toArray(null, true, true, true),
];
json_encode($payload);

Type guard

function isJsonEncodable(mixed $v): bool
{
    return !($v instanceof \PhpOffice\PhpSpreadsheet\Spreadsheet);
}

Try / catch

try {
    $json = json_encode($spreadsheet, flags: JSON_THROW_ON_ERROR);
} catch (\JsonException | \PhpOffice\PhpSpreadsheet\Exception $e) {
    $json = json_encode($spreadsheet->getActiveSheet()->toArray(null, true, true, true));
}

Prevention

When it happens

Trigger: json_encode($spreadsheet); returning a Spreadsheet from a Laravel/API controller (response()->json(...)); serializers (Symfony serializer, JMS) configured to walk JsonSerializable objects; logging frameworks that JSON-dump context variables that happen to hold a Spreadsheet.

Common situations: REST endpoints that try to echo an export object instead of the generated file; debug logging of large state arrays; queues serializing payloads to JSON; generic 'toArray then json' helper applied to the wrong object.

Related errors


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