{"record":{"id":"84bb0a3e21e88f94","repo":"PHPOffice/PhpSpreadsheet","slug":"maximum-31-characters-allowed-in-sheet-title","errorCode":null,"errorMessage":"Maximum 31 characters allowed in sheet title.","messagePattern":"Maximum 31 characters allowed in sheet title\\.","errorType":"exception","errorClass":"PhpOffice\\PhpSpreadsheet\\Exception","httpStatus":null,"severity":"error","filePath":"src/PhpSpreadsheet/Worksheet/Worksheet.php","lineNumber":475,"sourceCode":"    }\n\n    /**\n     * Check sheet title for valid Excel syntax.\n     *\n     * @param string $sheetTitle The string to check\n     *\n     * @return string The valid string\n     */\n    private static function checkSheetTitle(string $sheetTitle): string\n    {\n        // Some of the printable ASCII characters are invalid:  * : / \\ ? [ ]\n        if (str_replace(self::INVALID_CHARACTERS, '', $sheetTitle) !== $sheetTitle) {\n            throw new Exception('Invalid character found in sheet title');\n        }\n\n        // Enforce maximum characters allowed for sheet title\n        if (StringHelper::countCharacters($sheetTitle) > self::SHEET_TITLE_MAXIMUM_LENGTH) {\n            throw new Exception('Maximum ' . self::SHEET_TITLE_MAXIMUM_LENGTH . ' characters allowed in sheet title.');\n        }\n\n        return $sheetTitle;\n    }\n\n    /**\n     * Get a sorted list of all cell coordinates currently held in the collection by row and column.\n     *\n     * @param bool $sorted Also sort the cell collection?\n     *\n     * @return string[]\n     */\n    public function getCoordinates(bool $sorted = true): array\n    {\n        if (!isset($this->cellCollection)) { //* @phpstan-ignore isset.initializedProperty (may be null at destruct time)\n            return [];\n        }\n","sourceCodeStart":457,"sourceCodeEnd":493,"githubUrl":"https://github.com/PHPOffice/PhpSpreadsheet/blob/65b080eef4d9fd11a5796135ab145883e5c3d6a6/src/PhpSpreadsheet/Worksheet/Worksheet.php#L457-L493","documentation":"Thrown by Worksheet::checkSheetTitle() (via setTitle()) when the title exceeds self::SHEET_TITLE_MAXIMUM_LENGTH, which is 31 characters (counted multibyte-safely via StringHelper). Excel's tab-name limit is 31 chars, and PhpSpreadsheet enforces it rather than truncating silently.","triggerScenarios":"$sheet->setTitle('Very Long Descriptive Report Name ...') over 31 chars; setTitle($userProvidedName) with unconstrained input; also hits createSheet()->setTitle() chains in report generators.","commonSituations":"Report/export generators building titles from entity names + dates; localized (CJK/accented) names where byte length differs from character length; iterating versions of a name until one fits but forgetting the length cap.","solutions":["Truncate multibyte-safely: $sheet->setTitle(mb_substr($title, 0, 31))","Validate length where the title enters your code: if (mb_strlen($title) > 31) shorten it deterministically (e.g. ellipsize)","Keep a fixed short prefix plus a counter for generated sheets ('Report_1', 'Report_2')"],"exampleFix":"// before\n$sheet->setTitle('Consolidated Revenue Overview for Fiscal Year 2024 - EU Region'); // > 31 chars\n\n// after\n$title = 'Consolidated Revenue Overview for Fiscal Year 2024 - EU Region';\n$sheet->setTitle(mb_substr($title, 0, 31));","handlingStrategy":"validation","validationCode":"$title = mb_substr($title, 0, 31);\n$sheet->setTitle($title);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Truncate with mb_substr, never substr, for multibyte titles","Assert mb_strlen($title) <= 31 in report generators before setTitle","When uniqueness matters, reserve room for a suffix within the 31-char budget"],"tags":["phpspreadsheet","worksheet","sheet-title","length-limit","validation"],"backgroundTag":"name-length-limit-exceeded","analyzedSha":"65b080eef4d9fd11a5796135ab145883e5c3d6a6","analyzedAt":"2026-08-17T05:40:41.646Z","schemaVersion":2},"datasetVersion":"2026-08-17T09:17:11.063Z"}