Create pdftoword.html
Browse files- pdftoword.html +74 -0
pdftoword.html
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!DOCTYPE html>
|
| 2 |
+
<html lang="en">
|
| 3 |
+
<head>
|
| 4 |
+
<meta charset="UTF-8">
|
| 5 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 6 |
+
<title>PDFix — PDF to Word</title>
|
| 7 |
+
<style>
|
| 8 |
+
:root{--ink:#172033;--muted:#667085;--line:#e4e9f1;--blue:#2864e8;--blue-dark:#1747b8;--bg:#f4f7fb;--soft:#edf3ff;--green:#13865b;--red:#c93434}
|
| 9 |
+
*{box-sizing:border-box}body{margin:0;background:var(--bg);color:var(--ink);font-family:Inter,Segoe UI,Arial,sans-serif}
|
| 10 |
+
header{height:68px;background:#fff;border-bottom:1px solid var(--line);display:flex;align-items:center;justify-content:space-between;padding:0 24px;gap:12px}
|
| 11 |
+
.brand{display:flex;align-items:center;gap:10px;font-size:21px;font-weight:850;letter-spacing:-.5px}.logo{width:36px;height:36px;border-radius:10px;background:linear-gradient(135deg,#2864e8,#7c4dff);display:grid;place-items:center;color:white;font-weight:900}.brand small{display:block;font-size:10px;letter-spacing:1.7px;color:var(--muted);margin-top:2px}
|
| 12 |
+
a{color:inherit;text-decoration:none}.back{border:1px solid var(--line);padding:9px 12px;border-radius:9px;font-size:13px;font-weight:700;background:#fff}
|
| 13 |
+
main{max-width:1080px;margin:38px auto;padding:0 18px}.hero{text-align:center;margin:0 auto 28px;max-width:720px}.badge{display:inline-block;background:var(--soft);color:var(--blue);font-size:12px;font-weight:800;padding:7px 11px;border-radius:999px}.hero h1{font-size:clamp(30px,5vw,46px);letter-spacing:-1.5px;margin:16px 0 10px}.hero p{color:var(--muted);line-height:1.7;margin:0}
|
| 14 |
+
.card{background:white;border:1px solid var(--line);border-radius:18px;box-shadow:0 12px 32px rgba(22,34,61,.07);padding:24px;max-width:820px;margin:0 auto}
|
| 15 |
+
.drop{border:2px dashed #b9c9e8;background:#f9fbff;border-radius:15px;min-height:220px;display:flex;align-items:center;justify-content:center;text-align:center;padding:25px;transition:.2s}.drop.drag{border-color:var(--blue);background:var(--soft)}.drop .icon{font-size:46px}.drop h2{margin:9px 0;font-size:20px}.drop p{margin:0;color:var(--muted);font-size:14px;line-height:1.6}.btn{border:1px solid var(--line);background:#fff;color:var(--ink);border-radius:10px;padding:11px 15px;font-weight:750;cursor:pointer}.btn.primary{background:var(--blue);border-color:var(--blue);color:white}.btn.primary:hover{background:var(--blue-dark)}.btn:disabled{opacity:.5;cursor:not-allowed}.choose{display:inline-block;margin-top:16px}.file-row{display:flex;align-items:center;gap:12px;padding:14px;border:1px solid var(--line);border-radius:12px;margin-top:16px;display:none}.file-icon{width:44px;height:48px;border-radius:8px;background:#fff0f0;color:#c93434;display:grid;place-items:center;font-size:11px;font-weight:900;border:1px solid #f4d5d5}.file-info{flex:1;min-width:0}.file-info strong{display:block;overflow-wrap:anywhere}.file-info small{color:var(--muted);display:block;margin-top:5px}.options{display:grid;grid-template-columns:1fr 1fr;gap:14px;margin-top:20px}.option{padding:15px;border:1px solid var(--line);border-radius:12px}.option label{font-weight:800;font-size:13px;display:block;margin-bottom:8px}.option p{font-size:12px;color:var(--muted);line-height:1.5;margin:0}.option select{width:100%;padding:10px;border:1px solid var(--line);border-radius:9px;background:#fff}.action-row{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap;margin-top:22px}.status{font-size:13px;color:var(--muted);line-height:1.5;min-height:20px}.progress-wrap{display:none;margin-top:18px}.progress-track{height:8px;border-radius:20px;background:#e8edf5;overflow:hidden}.progress-bar{height:100%;width:0;background:linear-gradient(90deg,#2864e8,#7c4dff);transition:width .25s}.progress-label{font-size:12px;color:var(--muted);margin:8px 0}.result{display:none;margin-top:20px;padding:16px;border:1px solid #bfe6d3;background:#f1fbf6;border-radius:12px}.result strong{color:var(--green)}.result p{font-size:13px;color:#37584a;line-height:1.6}.result .btn{margin-top:5px}.notice{max-width:820px;margin:18px auto 0;padding:15px 17px;border:1px solid #f1dfb0;background:#fffaf0;border-radius:12px;font-size:12px;color:#735b24;line-height:1.6}.features{display:grid;grid-template-columns:repeat(3,1fr);gap:12px;max-width:820px;margin:18px auto}.feature{background:#fff;border:1px solid var(--line);border-radius:12px;padding:15px}.feature b{font-size:13px}.feature p{font-size:12px;line-height:1.5;color:var(--muted);margin:6px 0 0}footer{text-align:center;padding:28px 12px;color:var(--muted);font-size:12px}
|
| 16 |
+
@media(max-width:650px){header{padding:0 13px}.brand{font-size:18px}main{margin-top:24px;padding:0 12px}.card{padding:14px}.options{grid-template-columns:1fr}.features{grid-template-columns:1fr}.drop{min-height:190px}.action-row{align-items:stretch}.action-row .btn{width:100%}}
|
| 17 |
+
</style>
|
| 18 |
+
</head>
|
| 19 |
+
<body>
|
| 20 |
+
<header>
|
| 21 |
+
<a class="brand" href="index.html"><span class="logo">P</span><span>PDFix<small>PDF TOOLS</small></span></a>
|
| 22 |
+
<a class="back" href="index.html">← All PDF tools</a>
|
| 23 |
+
</header>
|
| 24 |
+
<main>
|
| 25 |
+
<section class="hero">
|
| 26 |
+
<span class="badge">PDF CONVERTER</span>
|
| 27 |
+
<h1>Convert PDF to Word</h1>
|
| 28 |
+
<p>Turn a PDF into an editable Microsoft Word document (.docx). Upload a file to extract its text and create a Word document.</p>
|
| 29 |
+
</section>
|
| 30 |
+
<section class="card">
|
| 31 |
+
<div class="drop" id="dropZone">
|
| 32 |
+
<div>
|
| 33 |
+
<div class="icon">📄</div>
|
| 34 |
+
<h2>Drop your PDF here</h2>
|
| 35 |
+
<p>or choose a PDF file from your device.<br>Files are processed in your browser by this page.</p>
|
| 36 |
+
<label class="choose"><input id="fileInput" type="file" accept="application/pdf,.pdf" hidden><button class="btn primary" id="chooseBtn" type="button">Choose PDF file</button></label>
|
| 37 |
+
</div>
|
| 38 |
+
</div>
|
| 39 |
+
<div class="file-row" id="fileRow">
|
| 40 |
+
<div class="file-icon">PDF</div><div class="file-info"><strong id="fileName">document.pdf</strong><small id="fileMeta">Ready to convert</small></div><button class="btn" id="removeBtn" type="button">Remove</button>
|
| 41 |
+
</div>
|
| 42 |
+
<div class="options">
|
| 43 |
+
<div class="option"><label for="layoutMode">Conversion mode</label><select id="layoutMode"><option value="text">Editable text (recommended)</option><option value="page">Page-by-page text with page breaks</option></select><p>Extracts selectable text. Complex layouts, columns, tables and images may not retain their original appearance.</p></div>
|
| 44 |
+
<div class="option"><label for="fileNameOut">Word file name</label><input id="fileNameOut" value="converted-document" style="width:100%;padding:10px;border:1px solid var(--line);border-radius:9px" maxlength="100"><p>Your result will download as a .docx file.</p></div>
|
| 45 |
+
</div>
|
| 46 |
+
<div class="action-row"><div class="status" id="status">Choose a PDF to begin.</div><button class="btn primary" id="convertBtn" disabled>Convert to Word →</button></div>
|
| 47 |
+
<div class="progress-wrap" id="progressWrap"><div class="progress-track"><div class="progress-bar" id="progressBar"></div></div><div class="progress-label" id="progressLabel">Preparing…</div></div>
|
| 48 |
+
<div class="result" id="result"><strong>✓ Word document created</strong><p id="resultText">Your converted file is ready.</p><button class="btn primary" id="downloadBtn">Download Word document</button></div>
|
| 49 |
+
</section>
|
| 50 |
+
<section class="features">
|
| 51 |
+
<div class="feature"><b>🔒 Browser processing</b><p>This page processes the PDF locally in your browser; it does not send the PDF to a PDFix server.</p></div>
|
| 52 |
+
<div class="feature"><b>📝 Editable text</b><p>Extracted text can be edited in Word or a compatible word processor.</p></div>
|
| 53 |
+
<div class="feature"><b>⚡ Quick conversion</b><p>Works best with text-based PDFs that contain selectable text.</p></div>
|
| 54 |
+
</section>
|
| 55 |
+
<div class="notice"><b>Conversion limitations:</b> This browser-only converter extracts text and creates a DOCX file. It does not perform full visual reconstruction of the original PDF, and scanned PDFs need OCR (not included here). Tables, images, columns, fonts and exact spacing may not be preserved. For sensitive documents, check the generated Word file before sharing it.</div>
|
| 56 |
+
</main>
|
| 57 |
+
<footer>PDFix · Simple PDF tools for everyday work</footer>
|
| 58 |
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.11.174/pdf.min.js"></script>
|
| 59 |
+
<script src="https://unpkg.com/docx@8.5.0/build/index.umd.js"></script>
|
| 60 |
+
<script>
|
| 61 |
+
pdfjsLib.GlobalWorkerOptions.workerSrc='https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.11.174/pdf.worker.min.js';
|
| 62 |
+
const $=id=>document.getElementById(id);
|
| 63 |
+
let selectedFile=null, resultBlob=null, resultName='converted-document.docx';
|
| 64 |
+
function setStatus(s){$('status').textContent=s}
|
| 65 |
+
function humanSize(n){if(n<1024)return n+' B';if(n<1024*1024)return (n/1024).toFixed(1)+' KB';return (n/1024/1024).toFixed(2)+' MB'}
|
| 66 |
+
function selectFile(file){if(!file)return;if(file.type!=='application/pdf'&&!file.name.toLowerCase().endsWith('.pdf')){alert('Please choose a PDF file.');return}selectedFile=file;$('fileRow').style.display='flex';$('fileName').textContent=file.name;$('fileMeta').textContent=humanSize(file.size)+' · Ready to convert';$('dropZone').style.display='none';$('convertBtn').disabled=false;$('result').style.display='none';$('progressWrap').style.display='none';resultBlob=null;setStatus('PDF selected. Ready to convert.');if(!$('fileNameOut').value||$('fileNameOut').value==='converted-document')$('fileNameOut').value=file.name.replace(/\.pdf$/i,'')}
|
| 67 |
+
function clearFile(){selectedFile=null;resultBlob=null;$('fileInput').value='';$('fileRow').style.display='none';$('dropZone').style.display='flex';$('convertBtn').disabled=true;$('result').style.display='none';$('progressWrap').style.display='none';setStatus('Choose a PDF to begin.')}
|
| 68 |
+
$('chooseBtn').onclick=()=>$('fileInput').click();$('fileInput').addEventListener('change',e=>selectFile(e.target.files[0]));$('removeBtn').onclick=clearFile;
|
| 69 |
+
const drop=$('dropZone');['dragenter','dragover'].forEach(n=>drop.addEventListener(n,e=>{e.preventDefault();drop.classList.add('drag')}));['dragleave','drop'].forEach(n=>drop.addEventListener(n,e=>{e.preventDefault();drop.classList.remove('drag')}));drop.addEventListener('drop',e=>selectFile(e.dataTransfer.files[0]));
|
| 70 |
+
$('convertBtn').onclick=async()=>{if(!selectedFile)return;const btn=$('convertBtn');btn.disabled=true;$('result').style.display='none';$('progressWrap').style.display='block';$('progressBar').style.width='3%';try{setStatus('Reading PDF…');$('progressLabel').textContent='Loading PDF…';const bytes=await selectedFile.arrayBuffer();const pdf=await pdfjsLib.getDocument({data:new Uint8Array(bytes)}).promise;const pages=[];for(let i=1;i<=pdf.numPages;i++){const page=await pdf.getPage(i);const content=await page.getTextContent();let lines=[];let currentLine=[],lastY=null;for(const item of content.items){if(!item.str)continue;const y=item.transform?item.transform[5]:0;if(lastY!==null&&Math.abs(y-lastY)>3){if(currentLine.length)lines.push(currentLine.join(''));currentLine=[]}currentLine.push(item.str);lastY=y}if(currentLine.length)lines.push(currentLine.join(''));pages.push(lines.join('\n'));const pct=Math.round(i/pdf.numPages*70)+5;$('progressBar').style.width=pct+'%';$('progressLabel').textContent=`Extracting text · page ${i} of ${pdf.numPages}`;setStatus(`Extracting text from page ${i} of ${pdf.numPages}…`)}const allEmpty=pages.every(t=>!t.trim());if(allEmpty){throw new Error('No selectable text was found. This may be a scanned PDF; OCR is not included in this version.')}const {Document,Packer,Paragraph,TextRun,PageBreak}=docx;const paras=[];const pageMode=$('layoutMode').value==='page';pages.forEach((text,index)=>{const clean=text.replace(/\r/g,'').split('\n');if(!clean.some(x=>x.trim()))clean.push('[No selectable text on this page]');clean.forEach(line=>paras.push(new Paragraph({children:[new TextRun({text:line})],spacing:{after:100}})));if(pageMode&&index<pages.length-1)paras.push(new Paragraph({children:[new PageBreak()]}))});$('progressBar').style.width='82%';$('progressLabel').textContent='Building Word document…';const doc=new Document({sections:[{properties:{},children:paras}]});resultBlob=await Packer.toBlob(doc);let name=$('fileNameOut').value.trim()||'converted-document';name=name.replace(/\.docx$/i,'').replace(/[\\/:*?"<>|]/g,'-');resultName=name+'.docx';$('progressBar').style.width='100%';$('progressLabel').textContent='Conversion complete';$('resultText').textContent=`Created ${resultName} from ${pdf.numPages} PDF page(s). The document contains extracted editable text; original layout and images may differ.`;$('result').style.display='block';setStatus('Conversion complete. Download your Word document below.');}catch(err){console.error(err);setStatus(err.message||'Conversion failed.');$('progressLabel').textContent=err.message||'Conversion failed.';$('progressBar').style.width='100%';alert(err.message||'Could not convert this PDF.')}finally{btn.disabled=false}};
|
| 71 |
+
$('downloadBtn').onclick=()=>{if(!resultBlob)return;const url=URL.createObjectURL(resultBlob);const a=document.createElement('a');a.href=url;a.download=resultName;a.click();setTimeout(()=>URL.revokeObjectURL(url),1500)};
|
| 72 |
+
</script>
|
| 73 |
+
</body>
|
| 74 |
+
</html>
|