PHPOffice/PhpSpreadsheet · error · PhpOffice\PhpSpreadsheet\Calculation\Exception

#NUM!

#NUM!

Error message

#NUM!

What it means

Table::setName() enforces Excel's 255-character ceiling for table names using StringHelper::countCharacters(), which counts Unicode code points rather than bytes. Names longer than 255 characters cannot round-trip through Excel's defined-name and table structures, so the library rejects them up front.

Source

Thrown at src/PhpSpreadsheet/Calculation/DateTimeExcel/Helpers.php:57

            }

            return $retval;
        }

        self::nullFalseTrueToNumber($dateValue, $allowBool, $calendar);
        if (!is_numeric($dateValue)) {
            $saveReturnDateType = Functions::getReturnDateType();
            Functions::setReturnDateType(Functions::RETURNDATE_EXCEL);
            if (is_string($dateValue)) {
                $dateValue = DateValue::fromString($dateValue);
            }
            Functions::setReturnDateType($saveReturnDateType);
            if (!is_numeric($dateValue)) {
                throw new Exception(ExcelError::VALUE());
            }
        }
        if ($dateValue < 0 && Functions::getCompatibilityMode() !== Functions::COMPATIBILITY_OPENOFFICE) {
            throw new Exception(ExcelError::NAN());
        }

        try {
            SharedDateHelper::excelToDateTimeObject((float) $dateValue, calendar: $calendar);
        } catch (Throwable) {
            throw new Exception(ExcelError::NAN());
        }

        return (float) $dateValue;
    }

    /**
     * getTimeValue.
     *
     * @return float|string Excel date/time serial value, or string if error
     */
    public static function getTimeValue(string $timeValue): string|float
    {

View on GitHub (pinned to 65b080eef4)

Solutions

  1. Truncate before setting: $table->setName(mb_substr($name, 0, 255))
  2. Use a short generated slug ('tbl_' . $id) and keep the long text in a cell
  3. Enforce a length cap at the input layer for anything destined to become a table name

Example fix

// before
$table->setName($userProvidedTitle); // 300-character report title -> exception

// after
$table->setName(mb_substr($userProvidedTitle, 0, 255));
Defensive patterns

Strategy: validation

Validate before calling

if (mb_strlen($name) > 255) {
    $name = mb_substr($name, 0, 255);
}
$table->setName($name);

Try / catch

try {
    $table->setName($name);
} catch (\PhpOffice\PhpSpreadsheet\Exception $e) {
    $table->setName(mb_substr($name, 0, 255)); // truncate and retry once
}

Prevention

When it happens

Trigger: Names assembled from user text, full sentences, timestamps, or concatenated column lists exceeding 255 characters; multi-byte names pushed through a generator without any length cap.

Common situations: Auto-naming tables after report titles, file paths, or JSON payloads; template-based name generation without truncation.

Related errors


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