PHPOffice/PhpSpreadsheet · error · PhpOffice\PhpSpreadsheet\Calculation\Exception
#NUM!
#NUM!
Error message
#NUM!
What it means
SheetView::setView() accepts exactly three layout types - SheetView::SHEETVIEW_NORMAL ('normal'), SHEETVIEW_PAGE_LAYOUT ('pageLayout'), SHEETVIEW_PAGE_BREAK_PREVIEW ('pageBreakPreview') - or null, which is normalized to 'normal'. Anything else throws 'Invalid sheetview layout type.' because the values must match the OOXML sheetView view attribute. The match is exact, so casing and spelling matter.
Source
Thrown at src/PhpSpreadsheet/Calculation/DateTimeExcel/Difference.php:74
$PHPDiffDateObject = $PHPEndDateObject->diff($PHPStartDateObject);
$retVal = false;
$retVal = self::replaceRetValue($retVal, $unit, 'D') ?? self::datedifD($difference);
$retVal = self::replaceRetValue($retVal, $unit, 'M') ?? self::datedifM($PHPDiffDateObject);
$retVal = self::replaceRetValue($retVal, $unit, 'MD') ?? self::datedifMD($startDays, $endDays, $PHPEndDateObject, $PHPDiffDateObject);
$retVal = self::replaceRetValue($retVal, $unit, 'Y') ?? self::datedifY($PHPDiffDateObject);
$retVal = self::replaceRetValue($retVal, $unit, 'YD') ?? self::datedifYD($difference, $startYears, $endYears, $PHPStartDateObject, $PHPEndDateObject);
$retVal = self::replaceRetValue($retVal, $unit, 'YM') ?? self::datedifYM($PHPDiffDateObject);
return is_bool($retVal) ? ExcelError::VALUE() : $retVal;
}
private static function initialDiff(float $startDate, float $endDate): float
{
// Validate parameters
if ($startDate > $endDate) {
throw new Exception(ExcelError::NAN());
}
return $endDate - $startDate;
}
/**
* Decide whether it's time to set retVal.
*/
private static function replaceRetValue(bool|int $retVal, string $unit, string $compare): null|bool|int
{
if ($retVal !== false || $unit !== $compare) {
return $retVal;
}
return null;
}
private static function datedifD(float $difference): intView on GitHub (pinned to 65b080eef4)
Solutions
- Use the constants: setView(SheetView::SHEETVIEW_PAGE_BREAK_PREVIEW)
- Map/whitelist external values to the three constants before calling
- Pass null when you want the default normal view
Example fix
// before
$sheet->getSheetView()->setView('PageLayout'); // wrong case -> exception
// after
use PhpOffice\PhpSpreadsheet\Worksheet\SheetView;
$sheet->getSheetView()->setView(SheetView::SHEETVIEW_PAGE_LAYOUT); Defensive patterns
Strategy: type-guard
Validate before calling
$allowed = [SheetView::SHEETVIEW_NORMAL, SheetView::SHEETVIEW_PAGE_LAYOUT, SheetView::SHEETVIEW_PAGE_BREAK_PREVIEW]; $viewType = in_array($candidate, $allowed, true) ? $candidate : null; // null -> normal $sheet->getSheetView()->setView($viewType);
Type guard
function isValidSheetViewType(?string $type): bool
{
return in_array($type, ['normal', 'pageLayout', 'pageBreakPreview'], true);
} Try / catch
try {
$sheet->getSheetView()->setView($viewType);
} catch (\PhpOffice\PhpSpreadsheet\Exception $e) {
$sheet->getSheetView()->setView(null); // default to normal
} Prevention
- Always use the SheetView::SHEETVIEW_* constants, never string literals
- Whitelist config/user input against the three constants before calling setView
- The comparison is case-sensitive: 'PageLayout' is invalid
When it happens
Trigger: setView('PageLayout') (wrong case), setView('pagebreakpreview'), setView('page_break_preview'), or forwarding a view name produced by another library, a config file, or a legacy PHPExcel codebase into this setter.
Common situations: Hardcoded strings instead of the class constants; user- or config-supplied view names; uppercase or underscore variants that 'look right' but are not the exact OOXML token.
Related errors
- Invalid visibility value.
- invalid dynamic rule type $dynamicRuleType
- Invalid filter type for column AutoFilter.
- Invalid rule connection for column AutoFilter.
- Invalid rule type for column AutoFilter Rule.
AI-assisted analysis of PHPOffice/PhpSpreadsheet@65b080eef4 (2026-08-17).
Data as JSON: /api/errors/8baa1352ee698e5a.
Report an issue: GitHub.