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
- Convert to data first: $rows = $spreadsheet->getActiveSheet()->toArray(null, true, true, true); then json_encode($rows).
- Save to a file and return the path/URL instead of the object: IOFactory::createWriter($spreadsheet, 'Xlsx')->save($path);
- Extract only the fields you need (sheet names, specific cell ranges) into a plain array before encoding.
- 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
- Return generated files or extracted arrays from APIs, never the object.
- Keep Spreadsheet out of log context and queue payloads.
- Centralize a toPayload($spreadsheet) helper for consistent extraction.
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
- Unsupported binary comparison operator
- Cloning the calculation engine is not allowed!
- Unsupported numeric binary operation
- Locale file not found
- #VALUE!
AI-assisted analysis of PHPOffice/PhpSpreadsheet@65b080eef4 (2026-08-17).
Data as JSON: /api/errors/0caa9d09203e7750.
Report an issue: GitHub.