PDF to HTML Converter
LocalRebuild PDF text as a standalone semantic HTML page
Drag & drop files here or click to browse
PDF • Max 50 MB
Files are processed in your browser and never uploaded
Privacy First
Your files are processed entirely in your browser. Nothing is uploaded to any server.
How do I convert a PDF into an HTML page?
Load the PDF and run the converter to download one self-contained .html file. The text layer is rebuilt into headings, paragraphs and lists, then written as semantic HTML with a small embedded stylesheet — no external CSS, no images, no scripts. The page title comes from the PDF’s Title metadata, or from the filename when there is none. The document is never uploaded.
About the PDF to HTML Converter
Rebuild a PDF’s text layer as one standalone HTML5 file. Lines are reconstructed from glyph positions and merged into paragraphs, headings are inferred from relative font size and written as h1 to h3, bullet and numbered lines become ul and ol lists, monospace runs become pre blocks, and running headers or footers repeated on three or more pages are dropped. The page is self-contained: UTF-8, a small embedded stylesheet, no external files and no scripts, so it opens correctly from a folder or an email attachment. The title comes from the PDF’s own Title metadata when it has one, and from the filename when it does not. What it does not do: it is not a visual copy of the page. Columns, exact positioning and tables are not reproduced — a table arrives as a run of lines. Images are not carried across. A scanned PDF has no text layer and produces a warning instead of a page.
- Publish the contents of a PDF report on an intranet or docs site as real HTML that search and screen readers can work through, instead of an embedded viewer.
- Get a semantic skeleton — headings, paragraphs, lists — to paste into a CMS, rather than the div-per-line soup a layout-faithful converter produces.
- Read a long PDF comfortably on a phone: the output reflows to the screen width instead of asking you to pinch and pan a fixed page.
- Diff two revisions of a document in a text-based tool by comparing generated HTML, where a heading change shows up as a heading change.
How to use the PDF to HTML tool
- 1
Upload PDF file
Select PDF file from your device or drag file into the upload area.
- 2
Choose settings
Choose settings such as Insert page separators before processing.
- 3
Convert to HTML
Run the PDF to HTML tool to create the HTML output.
- 4
Download the result
Download the finished file. The original file stays on your device and is not uploaded.
Is the HTML a pixel-accurate copy of the PDF page?
No, and that is the deliberate choice. Converters that chase visual fidelity emit one absolutely positioned div per line of text, which looks right at one window width and is useless for anything else: it does not reflow, it does not read well in a screen reader, and search engines see a pile of divs. This converter produces h1 to h3, p, ul, ol and pre instead. You get a page that reflows on a phone and that a machine can parse, and you give up the exact column layout and typography of the original.
What is actually inside the file it produces?
One HTML5 document and nothing else. A UTF-8 charset declaration, a viewport meta tag so it is readable on a phone, a title element, roughly twenty lines of CSS in a style block, and the body content. There are no linked stylesheets, no fonts to fetch, no JavaScript and no image files sitting next to it, so the page renders identically from a USB stick, an email attachment or a web server. Every piece of text is HTML-escaped, so a PDF that contains angle brackets or ampersands cannot produce broken markup.
What gets lost that was in the PDF?
Images, first: the output is text only, so photographs, charts and logos are not carried across. Use Extract Images From PDF if you need them, or PDF to PNG if what you want is a picture of the page. Tables lose their grid and arrive as consecutive lines. Exact fonts, colours, margins and column arrangement are replaced by the embedded stylesheet. Links written as PDF annotations are not converted into anchors. What survives is the words and the structural relationship between them.
Where does the page title come from?
From the PDF’s document information dictionary when that carries a usable Title, and from the filename with its extension removed when it does not. Many PDFs are exported with a Title that is really a template name or a full filesystem path, so a value containing no letters or digits at all is rejected in favour of the filename. Whichever wins is written into the title element and is what a browser tab, a bookmark and a search result will show for the page.
Are my files uploaded when converting PDF to HTML?
No. The PDF is opened by the pdf.js engine already running in this tab, the HTML is assembled as a string in memory, and your browser hands you that string as a download. Nothing crosses the network in either direction after the page itself has loaded — which is the practical difference from every hosted PDF-to-HTML service, all of which need the document on their server before they can begin.
Convert a PDF to HTML in code
Two different jobs hide behind this one phrase. The first three commands reproduce the page visually, with absolutely positioned text; the last snippet does what this page does, which is recover structure and throw the layout away. Pick by what you need the HTML for.
Shell (poppler)
pdftohtml is the standard answer. -s keeps it to one document, -i drops the images.
# macOS: brew install poppler Debian/Ubuntu: apt install poppler-utils
pdftohtml -s -i -noframes report.pdf report.html
# Keep the images as separate files next to the HTML
pdftohtml -s -noframes report.pdf report.htmlShell (mutool)
MuPDF emits font sizes and positions, which is what makes the output worth post-processing.
# macOS: brew install mupdf-tools Debian/Ubuntu: apt install mupdf-tools
mutool convert -F html -o report.html report.pdf
# The same page geometry as XML, if you would rather parse it yourself
mutool draw -F stext -o report.xml report.pdfNode.js (pdfjs-dist)
Structure from font size: the same rule this page uses, in about fifteen lines.
import { getDocument } from "pdfjs-dist/legacy/build/pdf.mjs"
import { readFile } from "node:fs/promises"
const pdf = await getDocument({ data: new Uint8Array(await readFile("report.pdf")) }).promise
const page = await pdf.getPage(1)
const { items } = await page.getTextContent()
// Math.hypot(transform[2], transform[3]) is the rendered font size
const lines = items
.filter((item) => item.str.trim())
.map((item) => ({
text: item.str,
size: Math.round(Math.hypot(item.transform[2], item.transform[3])),
}))
const body = lines.map((line) => line.size).sort()[Math.floor(lines.length / 2)]
const escape = (s) => s.replace(/&/g, "&").replace(/</g, "<")
for (const line of lines) {
const tag = line.size >= body * 1.15 ? "h2" : "p"
console.log(`<${tag}>${escape(line.text)}</${tag}>`)
}How to do this offline, on the command line
Poppler and MuPDF both ship a converter. Neither produces the semantic markup this page does — they reproduce the page, which is the other reasonable answer to the same question.
pdftohtml
macOS: brew install poppler · Debian/Ubuntu: apt install poppler-utils
pdftohtml -s -i -noframes report.pdf report.htmlWrites one absolutely positioned span per text run, so the result looks like the page and does not reflow. Drop -i to also write the embedded images out beside the HTML.
mutool
macOS: brew install mupdf-tools · Debian/Ubuntu: apt install mupdf-tools
mutool convert -F html -o report.html report.pdfAlso position-based, but it records font sizes in the markup, which gives a post-processing step something to turn into heading levels.
Frequently Asked Questions
Need More Tools?
Explore our collection of 58 free PDF tools, all with privacy-first processing.
Browse All Tools