✦ 100% Free · No Signup

Convert HTML to PDF
Instantly & Free

Paste HTML code or upload an .html file. Fine-tune settings and download a pixel-perfect PDF instantly.

🔒 Runs entirely in your browser 🎨 CSS styles preserved 📄 Auto multi-page support
Quick Templates
HTML Input
🌐

Drop your HTML file here

Supports .html and .htm files · CSS styles included

Browse File
🌐
Page margins
Auto multi-page

Rendering HTML…

✅ Your PDF is ready!

Why Use Our HTML→PDF Converter?

The most powerful free HTML-to-PDF tool — with full CSS support and instant downloads.

🎨

CSS Styles Preserved

Inline styles, embedded CSS, fonts, colors, layouts — all rendered faithfully using html2canvas technology.

📋

Quick Templates

Start instantly with pre-built templates for invoices, reports, letters, resumes, and certificates.

📄

Auto Multi-Page

Long HTML content is automatically split into multiple PDF pages. No content gets cut off.

🔒

100% Private

All rendering happens in your browser. Your HTML code is never sent to any server.

🆓

Always Free

No watermarks, no limits, no account. Completely free with no hidden costs, ever.

How It Works

Convert HTML to PDF in 3 Steps

1

Enter Your HTML

Paste HTML code directly into the editor, or upload an .html file. Use a template to start quickly.

2

Configure Settings

Adjust page size, orientation, scale, and quality settings to match your requirements.

3

Download PDF

Click "Convert to PDF" and instantly download a high-quality PDF with your HTML fully rendered.

Frequently Asked Questions

Does this support CSS styles and fonts?
Yes! Inline CSS and embedded <style> tags are fully supported. External fonts (Google Fonts) may not load depending on your browser security settings. Inline styles always work best.
Is my HTML code sent to any server?
No. All rendering and PDF generation happens entirely in your browser using html2canvas and jsPDF. Your code is never transmitted anywhere.
Can I convert long HTML documents to multi-page PDFs?
Yes! Enable "Auto multi-page" in the settings. Long content is automatically split across multiple pages so nothing gets cut off.
What's the best scale setting for a good result?
We recommend 85% scale for most documents. Use 75% for content-heavy pages or if the right edge gets clipped. Use 100% for simple, centered content.
Can I use this to convert a web page URL to PDF?
This tool works with HTML code and .html files. For URL-based conversion, save the page as HTML first (Ctrl+S in your browser), then upload the file here.
Trustpilot
`, report: `

📊 Q1 2025 Performance Report

Prepared by: Analytics Team · Date: April 28, 2025
$2.4M
Total Revenue
+18%
YoY Growth
4,820
New Customers
94%
Retention Rate

Executive Summary

The first quarter of 2025 demonstrated strong growth across all key performance indicators. Revenue exceeded projections by 12%, driven primarily by enterprise contracts and product expansion into new markets.

Key Highlights

Customer acquisition improved significantly due to optimized marketing funnels. The new onboarding flow reduced churn by 22% compared to Q4 2024. Product development velocity increased with the launch of 3 major features.

Outlook for Q2

Based on current pipeline, Q2 is projected to continue the upward trend with 15-20% revenue growth. Focus areas include expanding the partner ecosystem and improving customer success processes.

`, letter: `
John Smith
456 Maple Street
San Francisco, CA 94102
john.smith@email.com
April 28, 2025
Ms. Emily Johnson
Director of Operations
Sunrise Technologies Inc.
789 Innovation Drive
Austin, TX 73301
Dear Ms. Johnson,

I am writing to express my sincere interest in the Senior Product Manager position at Sunrise Technologies Inc. Having followed your company's remarkable growth over the past three years, I am confident that my background in product development and cross-functional leadership would make a meaningful contribution to your team.

In my current role at GlobalSoft, I led a team of 12 engineers and designers in delivering a flagship product that increased annual recurring revenue by $3.2 million. I am particularly proud of my work streamlining agile processes and establishing a culture of continuous improvement.

I would welcome the opportunity to discuss how my experience aligns with your needs. Please find my resume attached for your consideration. I look forward to hearing from you.

Yours sincerely,
John Smith
`, resume: `

Alex Rivera

Senior Software Engineer
alex.rivera@email.com
+1 (555) 234-5678
github.com/alexrivera
San Francisco, CA

Experience

Senior Software EngineerJan 2022 – Present
TechCorp Inc. · San Francisco, CA
Software EngineerJun 2019 – Dec 2021
StartupXYZ · Remote

Education

B.S. Computer Science2015 – 2019
University of California, Berkeley · GPA: 3.8

Skills

JavaScriptTypeScriptReactNode.jsPythonAWSDockerPostgreSQLRedisGraphQL
`, certificate: `
✦ GPTPayer.online Academy ✦

Certificate of Achievement

This certifies that
Jane Marie Doe

has successfully completed the Advanced Web Development Mastery Program with distinction, demonstrating exceptional knowledge in modern web technologies and best practices.

Date Issued
April 28, 2025
Certificate ID
CERT-2025-4821
Authorized By
Dr. Alan Turner
` }; function loadTemplate(key) { const input = document.getElementById('html-input'); input.value = TEMPLATES[key] || ''; } function switchTab(mode) { activeMode = mode; document.getElementById('pane-editor').classList.toggle('active', mode === 'editor'); document.getElementById('pane-upload').classList.toggle('active', mode === 'upload'); document.getElementById('tab-editor').classList.toggle('active', mode === 'editor'); document.getElementById('tab-upload').classList.toggle('active', mode === 'upload'); } // Upload const fileInput = document.getElementById('fileInput'); const dropZone = document.getElementById('dropZone'); fileInput.addEventListener('change', e => { if (e.target.files[0]) loadHTMLFile(e.target.files[0]); }); dropZone.addEventListener('dragover', e => { e.preventDefault(); dropZone.classList.add('drag-over'); }); dropZone.addEventListener('dragleave', () => dropZone.classList.remove('drag-over')); dropZone.addEventListener('drop', e => { e.preventDefault(); dropZone.classList.remove('drag-over'); if (e.dataTransfer.files[0]) loadHTMLFile(e.dataTransfer.files[0]); }); // ─── SEARCHABLE PDF MODE ────────────────────────────────── async function convertToSearchablePDF() { const rawHtml = document.getElementById('searchable-input').value.trim(); if (!rawHtml) { alert('Please enter some HTML content first.'); return; } const btn = document.getElementById('btnConvert'); btn.disabled = true; btn.textContent = 'Building…'; const pw = document.getElementById('progress-bar-wrap'); const pf = document.getElementById('progressFill'); const pl = document.getElementById('progress-label'); pw.style.display = 'block'; pf.style.width = '20%'; pl.textContent = 'Parsing HTML…'; await new Promise(r => setTimeout(r, 60)); const pageSize = document.getElementById('pageSize').value; const orientation = document.getElementById('orientation').value; const filename = document.getElementById('filename').value.trim() || 'document'; const { jsPDF } = window.jspdf; const doc = new jsPDF({ orientation, unit: 'mm', format: pageSize }); const W = doc.internal.pageSize.getWidth(); const H = doc.internal.pageSize.getHeight(); const margin = 15; const maxW = W - margin * 2; let y = margin; function addPage() { doc.addPage(); y = margin; } function checkY(needed) { if (y + needed > H - margin) addPage(); } // Parse HTML into blocks const tmp = document.createElement('div'); tmp.innerHTML = rawHtml; const blocks = []; function walk(node) { if (node.nodeType === 3) { const t = node.textContent.trim(); if (t) blocks.push({ type: 'text', text: t }); return; } const tag = (node.tagName || '').toLowerCase(); if (['h1','h2','h3','h4','h5','h6'].includes(tag)) { blocks.push({ type: 'heading', level: parseInt(tag[1]), text: node.textContent.trim() }); } else if (tag === 'p') { const t = node.textContent.trim(); if (t) blocks.push({ type: 'para', text: t }); } else if (tag === 'li') { blocks.push({ type: 'li', text: '• ' + node.textContent.trim() }); } else if (['br','hr'].includes(tag)) { blocks.push({ type: 'br' }); } else if (['ul','ol','div','section','article','main','body'].includes(tag)) { node.childNodes.forEach(walk); } else { const t = node.textContent.trim(); if (t) blocks.push({ type: 'text', text: t }); } } tmp.childNodes.forEach(walk); pf.style.width = '50%'; pl.textContent = 'Rendering text…'; await new Promise(r => setTimeout(r, 40)); for (const block of blocks) { if (block.type === 'br') { y += 4; continue; } if (block.type === 'heading') { const sizes = [22, 18, 15, 13, 12, 11]; const sz = sizes[block.level - 1] || 14; doc.setFont('helvetica', 'bold'); doc.setFontSize(sz); doc.setTextColor(26, 23, 20); const lines = doc.splitTextToSize(block.text, maxW); checkY(lines.length * (sz * 0.45) + 4); doc.text(lines, margin, y); y += lines.length * (sz * 0.45) + 4; } else if (block.type === 'para' || block.type === 'text') { doc.setFont('helvetica', 'normal'); doc.setFontSize(11); doc.setTextColor(40, 40, 40); const lines = doc.splitTextToSize(block.text, maxW); checkY(lines.length * 5.5 + 3); doc.text(lines, margin, y); y += lines.length * 5.5 + 3; } else if (block.type === 'li') { doc.setFont('helvetica', 'normal'); doc.setFontSize(11); doc.setTextColor(40, 40, 40); const lines = doc.splitTextToSize(block.text, maxW - 5); checkY(lines.length * 5.5 + 2); doc.text(lines, margin + 3, y); y += lines.length * 5.5 + 2; } } // Footer on each page const pages = doc.internal.getNumberOfPages(); for (let p = 1; p <= pages; p++) { doc.setPage(p); doc.setFontSize(8); doc.setTextColor(160); doc.text('Page ' + p + ' / ' + pages, W - margin, H - 8, { align: 'right' }); } pf.style.width = '100%'; pl.textContent = 'Done!'; pdfBlob = doc.output('blob'); setTimeout(() => { pw.style.display = 'none'; document.getElementById('success-msg').style.display = 'block'; document.getElementById('download-info').textContent = pages + ' page(s) · Searchable text PDF · ' + formatSize(pdfBlob.size); btn.disabled = false; btn.textContent = 'Convert to PDF →'; }, 400); document.getElementById('btnDownload').onclick = () => { const url = URL.createObjectURL(pdfBlob); const a = document.createElement('a'); a.href = url; a.download = filename + '.pdf'; a.click(); URL.revokeObjectURL(url); }; } function formatSize(bytes) { if (bytes < 1048576) return (bytes/1024).toFixed(1) + ' KB'; return (bytes/1048576).toFixed(1) + ' MB'; } function loadHTMLFile(file) { const reader = new FileReader(); reader.onload = e => { uploadedHTML = e.target.result; dropZone.style.display = 'none'; document.getElementById('file-loaded-info').style.display = 'block'; document.getElementById('file-name-display').textContent = file.name; document.getElementById('file-meta-display').textContent = formatSize(file.size) + ' · ' + (file.name.split('.').pop().toUpperCase()); document.getElementById('filename').value = file.name.replace(/\.[^.]+$/, ''); }; reader.readAsText(file); } function clearUploadedFile() { uploadedHTML = ''; fileInput.value = ''; dropZone.style.display = 'block'; document.getElementById('file-loaded-info').style.display = 'none'; document.getElementById('success-msg').style.display = 'none'; } function clearAll() { if (activeMode === 'editor') { document.getElementById('html-input').value = ''; } else { clearUploadedFile(); } pdfBlob = null; document.getElementById('success-msg').style.display = 'none'; document.getElementById('progress-bar-wrap').style.display = 'none'; } async function convertToPDF() { if (activeMode === 'searchable') { return convertToSearchablePDF(); } const htmlContent = activeMode === 'editor' ? document.getElementById('html-input').value : uploadedHTML; if (!htmlContent.trim()) { alert('Please enter or upload HTML content first.'); return; } const btn = document.getElementById('btnConvert'); btn.disabled = true; btn.textContent = 'Rendering…'; const progressWrap = document.getElementById('progress-bar-wrap'); const progressFill = document.getElementById('progressFill'); const progressLabel = document.getElementById('progress-label'); progressWrap.style.display = 'block'; progressFill.style.width = '10%'; progressLabel.textContent = 'Loading HTML into renderer…'; await new Promise(r => setTimeout(r, 60)); const pageSize = document.getElementById('pageSize').value; const orientation = document.getElementById('orientation').value; const scale = parseFloat(document.getElementById('scale').value); const quality = parseFloat(document.getElementById('quality').value); const filename = document.getElementById('filename').value.trim() || 'converted'; const addMargins = document.getElementById('addMargins').checked; const multiPage = document.getElementById('multiPage').checked; // Render HTML directly into hidden div (avoids iframe cross-origin blank issue) const renderTarget = document.getElementById('render-target'); renderTarget.innerHTML = ''; // Create a sandboxed div with the user's HTML injected const renderDiv = document.createElement('div'); renderDiv.style.cssText = 'width:900px;background:#fff;padding:0;margin:0;box-sizing:border-box;'; renderDiv.innerHTML = htmlContent; renderTarget.appendChild(renderDiv); // Give browser time to lay out and paint await new Promise(r => setTimeout(r, 300)); progressFill.style.width = '35%'; progressLabel.textContent = 'Capturing page with html2canvas…'; await new Promise(r => setTimeout(r, 100)); try { const canvas = await html2canvas(renderDiv, { scale: quality, useCORS: true, allowTaint: true, backgroundColor: '#ffffff', logging: false, windowWidth: 900, }); progressFill.style.width = '75%'; progressLabel.textContent = 'Building PDF…'; await new Promise(r => setTimeout(r, 60)); const imgData = canvas.toDataURL('image/jpeg', 0.92); const { jsPDF } = window.jspdf; const doc = new jsPDF({ orientation, unit: 'mm', format: pageSize }); const pageW = doc.internal.pageSize.getWidth(); const pageH = doc.internal.pageSize.getHeight(); const margin = addMargins ? 10 : 0; const contentW = (pageW - margin * 2) * scale; const contentH = (canvas.height / canvas.width) * contentW; if (multiPage && contentH > pageH - margin * 2) { // Split into multiple pages const pageContentH = pageH - margin * 2; const totalPages = Math.ceil(contentH / pageContentH); for (let p = 0; p < totalPages; p++) { if (p > 0) doc.addPage(); const sliceCanvas = document.createElement('canvas'); const sliceH = Math.min( Math.round((pageContentH / contentH) * canvas.height), canvas.height - Math.round((p * pageContentH / contentH) * canvas.height) ); const sliceY = Math.round((p * pageContentH / contentH) * canvas.height); sliceCanvas.width = canvas.width; sliceCanvas.height = sliceH; const ctx = sliceCanvas.getContext('2d'); ctx.drawImage(canvas, 0, sliceY, canvas.width, sliceH, 0, 0, canvas.width, sliceH); const sliceData = sliceCanvas.toDataURL('image/jpeg', 0.92); const sliceDisplayH = (sliceH / canvas.height) * contentH; doc.addImage(sliceData, 'JPEG', margin, margin, contentW, sliceDisplayH); } } else { doc.addImage(imgData, 'JPEG', margin, margin, contentW, contentH); } progressFill.style.width = '100%'; progressLabel.textContent = 'Done!'; pdfBlob = doc.output('blob'); setTimeout(() => { progressWrap.style.display = 'none'; document.getElementById('success-msg').style.display = 'block'; document.getElementById('download-info').textContent = doc.internal.getNumberOfPages() + ' page(s) · ' + formatSize(pdfBlob.size); btn.disabled = false; btn.textContent = 'Convert to PDF →'; }, 500); document.getElementById('btnDownload').onclick = () => { const url = URL.createObjectURL(pdfBlob); const a = document.createElement('a'); a.href = url; a.download = filename + '.pdf'; a.click(); URL.revokeObjectURL(url); }; } catch(err) { console.error(err); progressWrap.style.display = 'none'; alert('Conversion failed. Please check your HTML for errors and try again.'); btn.disabled = false; btn.textContent = 'Convert to PDF →'; } finally { renderTarget.innerHTML = ''; } }