{"record":{"id":"362817ec337e8302","repo":"PHPOffice/PhpSpreadsheet","slug":"filename-is-an-invalid-html-file","errorCode":null,"errorMessage":"{filename} is an Invalid HTML file.","messagePattern":"(.+?) is an Invalid HTML file\\.","errorType":"exception","errorClass":"PhpOffice\\PhpSpreadsheet\\Exception","httpStatus":null,"severity":"error","filePath":"src/PhpSpreadsheet/Reader/Html.php","lineNumber":797,"sourceCode":"                }\n                //    simply append the text if the cell content is a plain text string\n                $cellContent .= $domText;\n                //    but if we have a rich text run instead, we need to append it correctly\n                //    TODO\n            } elseif ($child instanceof DOMElement) {\n                $this->processDomElementBody($sheet, $row, $column, $cellContent, $child);\n            }\n        }\n    }\n\n    /**\n     * Loads PhpSpreadsheet from file into PhpSpreadsheet instance.\n     */\n    public function loadIntoExisting(string $filename, Spreadsheet $spreadsheet): Spreadsheet\n    {\n        // Validate\n        if (!$this->canRead($filename)) {\n            throw new Exception($filename . ' is an Invalid HTML file.');\n        }\n\n        // Create a new DOM object\n        $dom = new DOMDocument();\n\n        // Reload the HTML file into the DOM object\n        if (is_bool($this->suppressLoadWarnings)) {\n            $useErrors = libxml_use_internal_errors($this->suppressLoadWarnings);\n        } else {\n            $useErrors = null;\n        }\n\n        try {\n            $convert = $this->getSecurityScannerOrThrow()->scanFile($filename);\n            $convert = static::replaceNonAsciiIfNeeded($convert);\n            $loaded = ($convert === null) ? false : $dom->loadHTML($convert);\n        } catch (Throwable $e) {\n            $loaded = false;","sourceCodeStart":779,"sourceCodeEnd":815,"githubUrl":"https://github.com/PHPOffice/PhpSpreadsheet/blob/65b080eef4d9fd11a5796135ab145883e5c3d6a6/src/PhpSpreadsheet/Reader/Html.php#L779-L815","documentation":"The Html reader's loadIntoExisting() guards itself with canRead(), which sniffs for recognizable HTML markup. When the check fails it throws 'Invalid HTML file' before DOM parsing starts — the content does not look like HTML to the reader's heuristic.","triggerScenarios":"loadIntoExisting() on a file that is actually plain text, JSON, XML, or empty; Excel's 'Single File Web Page' (.mht) exports, which the HTML reader cannot recognize; files whose markup is buried after large non-markup preamble so the sniff misses it.","commonSituations":"Feeding scraped or API-returned content saved as .html; user uploads validated only by extension; importing mail-exported .mht files.","solutions":["Use IOFactory::identify() and the matching reader instead of hardcoding Html","If the file must be HTML, verify the leading bytes contain real markup (e.g. str_contains strtolower for '<html' or '<table') before loading","Convert .mht to plain .html (open in a browser or mail client and re-save) before import"],"exampleFix":"// before\n$spreadsheet = (new Html())->loadIntoExisting('export.mht', $spreadsheet); // MHT not recognized -> throws\n\n// after\n$type = IOFactory::identify($uploadPath);\n$reader = IOFactory::createReader($type);\n$spreadsheet = $reader->loadIntoExisting($uploadPath, $spreadsheet);","handlingStrategy":"validation","validationCode":"$head = substr((string) file_get_contents($filename), 0, 2048);\nif (!str_contains(strtolower($head), '<')) {\n    throw new RuntimeException('File contains no HTML markup');\n}\n$spreadsheet = (new Html())->loadIntoExisting($filename, $spreadsheet);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Check for markup markers before invoking the Html reader","Convert .mht exports to plain HTML prior to import","Route unknown files through IOFactory::identify()"],"tags":["html","format-detection","file-validation","mht"],"backgroundTag":"file-format-not-recognized","analyzedSha":"65b080eef4d9fd11a5796135ab145883e5c3d6a6","analyzedAt":"2026-08-17T05:40:41.646Z","schemaVersion":2},"datasetVersion":"2026-08-17T09:17:11.063Z"}