Spaces:
Sleeping
Sleeping
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8" /> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | |
| <title>PDF to Excel Converter</title> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <!-- PDF.js --> | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.8.162/pdf.min.js"></script> | |
| </head> | |
| <body class="bg-gray-900 text-gray-200 min-h-screen flex items-center justify-center p-6"> | |
| <div class="w-full max-w-2xl bg-gray-800 shadow-2xl rounded-2xl p-6"> | |
| <h2 class="text-3xl font-bold text-green-400 mb-6 text-center">Convert PDF to Excel</h2> | |
| <form id="convert-form" class="space-y-6"> | |
| <!-- File Upload --> | |
| <div class="border-2 border-dashed border-green-500 rounded-xl p-6 text-center cursor-pointer hover:bg-gray-700 transition"> | |
| <input type="file" name="pdf" id="pdf-input" accept="application/pdf" class="hidden" /> | |
| <label for="pdf-input" class="block cursor-pointer text-green-300 font-medium"> | |
| 📂 Click or drag your PDF here | |
| </label> | |
| </div> | |
| <!-- PDF Preview --> | |
| <div id="preview-container" class="hidden mt-4"> | |
| <h3 class="text-lg font-semibold text-green-300 mb-2">Live Preview</h3> | |
| <canvas id="pdf-preview" class="w-full rounded-lg shadow-lg border border-green-500"></canvas> | |
| </div> | |
| <!-- Convert Button --> | |
| <div class="text-center"> | |
| <button id="convert-btn" type="submit" class="hidden bg-green-600 text-white px-8 py-3 rounded-xl shadow-md hover:bg-green-700 transition font-semibold"> | |
| 🔄 Convert to Excel | |
| </button> | |
| </div> | |
| <!-- Progress --> | |
| <div id="progress" class="hidden mt-4 text-green-400 font-medium flex items-center gap-2 justify-center"> | |
| <svg class="animate-spin h-5 w-5 text-green-400" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"> | |
| <circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle> | |
| <path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"></path> | |
| </svg> | |
| Converting PDF... Please wait | |
| </div> | |
| </form> | |
| </div> | |
| <script> | |
| const fileInput = document.getElementById("pdf-input"); | |
| const previewContainer = document.getElementById("preview-container"); | |
| const canvas = document.getElementById("pdf-preview"); | |
| const ctx = canvas.getContext("2d"); | |
| // Show PDF preview | |
| fileInput.addEventListener("change", async (e) => { | |
| const file = e.target.files[0]; | |
| if (file && file.type === "application/pdf") { | |
| previewContainer.classList.remove("hidden"); | |
| document.getElementById('convert-btn').classList.remove('hidden'); | |
| const fileReader = new FileReader(); | |
| fileReader.onload = async function () { | |
| const typedarray = new Uint8Array(this.result); | |
| const pdf = await pdfjsLib.getDocument(typedarray).promise; | |
| const page = await pdf.getPage(1); | |
| const viewport = page.getViewport({ scale: 1.5 }); | |
| canvas.height = viewport.height; | |
| canvas.width = viewport.width; | |
| await page.render({ canvasContext: ctx, viewport: viewport }).promise; | |
| }; | |
| fileReader.readAsArrayBuffer(file); | |
| } else { | |
| previewContainer.classList.add("hidden"); | |
| } | |
| }); | |
| // Handle form submit | |
| document.getElementById("convert-form").addEventListener("submit", async function (e) { | |
| e.preventDefault(); | |
| const file = fileInput.files[0]; | |
| const button = document.getElementById("convert-btn"); | |
| const progress = document.getElementById("progress"); | |
| if (!file) return; | |
| button.disabled = true; | |
| button.classList.add("opacity-50", "cursor-not-allowed"); | |
| progress.classList.remove("hidden"); | |
| const formData = new FormData(); | |
| formData.append("pdf", file); | |
| const response = await fetch("/pdf-to-excel", { method: "POST", body: formData }); | |
| if (!response.ok) { | |
| alert("Conversion failed. Please try again."); | |
| button.disabled = false; | |
| button.classList.remove("opacity-50", "cursor-not-allowed"); | |
| progress.classList.add("hidden"); | |
| return; | |
| } | |
| const blob = await response.blob(); | |
| const downloadUrl = window.URL.createObjectURL(blob); | |
| const a = document.createElement("a"); | |
| a.href = downloadUrl; | |
| a.download = "output.xlsx"; | |
| document.body.appendChild(a); | |
| a.click(); | |
| a.remove(); | |
| button.disabled = false; | |
| button.classList.remove("opacity-50", "cursor-not-allowed"); | |
| progress.classList.add("hidden"); | |
| fileInput.value = ""; | |
| previewContainer.classList.add("hidden"); | |
| }); | |
| </script> | |
| </body> | |
| </html> |