POWERPOINT to PDF

POWERPOINT to PDF Converter | Convert PPT/PPTX to PDF
📁

Drop PowerPoint Files Here

or click to browse files

PPT
PPTX
ODP
0
Files
0
Converted
0 KB
Total Size
Presentation Preview
No Files
👁️

Preview Area

Select a PowerPoint file to preview its information here. Click on any file in the list to view details.

⚙️ PDF Settings
📄 Presentation Options
🔧 Convert & Export

Converting PowerPoint to PDF...

`; const blob = new Blob([htmlContent], {type: 'text/html'}); this.previewFrame.src = URL.createObjectURL(blob); this.previewInfo.innerHTML = ` ${file.name} ${file.type} • ${this.formatFileSize(file.size)} • ${file.slideCount} slides `; this.noPreview.style.display = 'none'; this.presentationPreview.style.display = 'block'; } async convertToPDF() { if (this.files.length === 0) { this.showMessage('No files to convert', 'error'); return; } this.showLoading(true); this.progressBar.style.display = 'block'; this.progressFill.style.width = '0%'; try { const { jsPDF } = window.jspdf; // Get conversion settings const pageSize = this.pageSizeSelect.value; const slidesPerPage = parseInt(this.slidesPerPage.value); const quality = this.qualitySelect.value; const title = this.pdfTitle.value || 'Converted Presentation'; const author = this.pdfAuthor.value || ''; const includeNotes = this.includeNotes.checked; // Page size mapping const pageSizes = { 'A4': { width: 210, height: 297 }, 'letter': { width: 215.9, height: 279.4 }, 'a3': { width: 297, height: 420 }, '16:9': { width: 297, height: 167 }, // Widescreen ratio '4:3': { width: 280, height: 210 } // Standard ratio }; const selectedSize = pageSizes[pageSize] || pageSizes['A4']; this.convertedFiles = []; for (let i = 0; i < this.files.length; i++) { const file = this.files[i]; // Update progress this.progressFill.style.width = `${((i + 1) / this.files.length) * 100}%`; // Update status file.status = 'converting'; this.renderFileList(); try { // Create PDF document const pdf = new jsPDF({ orientation: 'portrait', unit: 'mm', format: [selectedSize.width, selectedSize.height] }); // Set document properties pdf.setProperties({ title: title, author: author, creator: 'POWERPOINT to PDF Converter', subject: 'Converted from ' + file.name, keywords: 'presentation, powerpoint, slides, converted' }); // Add cover page pdf.setFontSize(24); pdf.setTextColor(40, 40, 40); pdf.text(title, selectedSize.width / 2, 50, { align: 'center' }); pdf.setFontSize(16); pdf.setTextColor(100, 100, 100); pdf.text(`Original: ${file.name}`, selectedSize.width / 2, 70, { align: 'center' }); pdf.setFontSize(14); pdf.text(`Converted: ${new Date().toLocaleDateString()}`, selectedSize.width / 2, 80, { align: 'center' }); pdf.text(`${file.slideCount} slides`, selectedSize.width / 2, 90, { align: 'center' }); // Add slide pages const slidesPerRow = slidesPerPage === 1 ? 1 : 2; const slidesPerCol = slidesPerPage <= 2 ? 1 : Math.ceil(slidesPerPage / 2); let currentSlide = 1; let currentPage = 1; while (currentSlide <= file.slideCount) { if (currentPage > 1) { pdf.addPage(); } // Add page header pdf.setFontSize(12); pdf.setTextColor(100, 100, 100); pdf.text(`${file.name} - Page ${currentPage}`, 20, 20); // Add slide representations if (slidesPerPage === 1) { // One slide per page this.addSlideRepresentation(pdf, currentSlide, selectedSize, 20, 30); } else { // Multiple slides per page const slideWidth = (selectedSize.width - 40) / slidesPerRow; const slideHeight = (selectedSize.height - 60) / slidesPerCol; for (let row = 0; row < slidesPerCol; row++) { for (let col = 0; col < slidesPerRow; col++) { if (currentSlide <= file.slideCount) { const x = 20 + (col * slideWidth); const y = 30 + (row * slideHeight); this.addSlideRepresentation( pdf, currentSlide, { width: slideWidth - 10, height: slideHeight - 20 }, x, y ); currentSlide++; } } } } currentPage++; // If slidesPerPage is 1, increment slide count if (slidesPerPage === 1) { currentSlide++; } } // Add notes page if requested if (includeNotes && file.slideCount > 0) { pdf.addPage(); pdf.setFontSize(18); pdf.setTextColor(40, 40, 40); pdf.text('Speaker Notes', selectedSize.width / 2, 30, { align: 'center' }); pdf.setFontSize(11); pdf.setTextColor(80, 80, 80); let y = 50; for (let note = 1; note <= Math.min(file.slideCount, 10); note++) { if (y > selectedSize.height - 20) { pdf.addPage(); y = 30; } pdf.setFontSize(12); pdf.setTextColor(40, 40, 40); pdf.text(`Slide ${note}:`, 20, y); pdf.setFontSize(10); pdf.setTextColor(100, 100, 100); pdf.text(`Sample speaker notes for slide ${note}. In a real conversion,`, 40, y + 7); pdf.text(`these would be extracted from the actual PowerPoint file.`, 40, y + 14); y += 30; } } // Save PDF const pdfBlob = pdf.output('blob'); file.convertedUrl = URL.createObjectURL(pdfBlob); file.status = 'converted'; this.convertedFiles.push({ file: file, pdfBlob: pdfBlob }); this.showMessage(`Converted ${file.name} to PDF`, 'success'); } catch (error) { console.error(`Error converting ${file.name}:`, error); file.status = 'pending'; this.showMessage(`Error converting ${file.name}`, 'error'); } // Update UI this.renderFileList(); this.updateStats(); // Small delay to show progress await new Promise(resolve => setTimeout(resolve, 300)); } // Complete progress this.progressFill.style.width = '100%'; // Update UI this.downloadBtn.disabled = this.convertedFiles.length === 0; if (this.convertedFiles.length > 0) { this.showMessage(`Successfully converted ${this.convertedFiles.length} presentation(s) to PDF`, 'success'); } } catch (error) { console.error('Error in conversion process:', error); this.showMessage('Error converting presentations to PDF', 'error'); } finally { setTimeout(() => { this.showLoading(false); this.progressBar.style.display = 'none'; }, 1000); } } addSlideRepresentation(pdf, slideNumber, size, x, y) { // Draw slide background pdf.setFillColor(240, 240, 240); pdf.rect(x, y, size.width, size.height, 'F'); // Draw slide border pdf.setDrawColor(200, 200, 200); pdf.setLineWidth(0.5); pdf.rect(x, y, size.width, size.height); // Add slide number pdf.setFontSize(10); pdf.setTextColor(150, 150, 150); pdf.text(`Slide ${slideNumber}`, x + 5, y + 10); // Add slide content representation pdf.setFontSize(14); pdf.setTextColor(80, 80, 80); pdf.text(`Slide ${slideNumber}`, x + size.width / 2, y + size.height / 2, { align: 'center' }); // Add a simple graphic representation pdf.setFillColor(78, 205, 196); pdf.circle(x + size.width / 2, y + size.height / 2 + 15, 5, 'F'); } downloadPDF() { if (this.convertedFiles.length === 0) { this.showMessage('No converted files to download', 'error'); return; } if (this.convertedFiles.length === 1) { // Single file download this.downloadSinglePDF(this.convertedFiles[0].file.id); } else { // Multiple files - download individually this.convertedFiles.forEach((convertedFile, index) => { setTimeout(() => { this.downloadSinglePDF(convertedFile.file.id); }, index * 500); }); this.showMessage(`Downloading ${this.convertedFiles.length} PDF file(s)`, 'success'); } } downloadSinglePDF(fileId) { const file = this.files.find(f => f.id === fileId); if (!file || !file.convertedUrl) { this.showMessage('File not ready for download', 'error'); return; } const link = document.createElement('a'); link.href = file.convertedUrl; link.download = file.name.replace(/\.[^/.]+$/, "") + '.pdf'; document.body.appendChild(link); link.click(); document.body.removeChild(link); } removeFile(fileId) { this.files = this.files.filter(file => file.id !== fileId); // Update preview if removed file was being previewed if (this.files.length === 0) { this.noPreview.style.display = 'flex'; this.presentationPreview.style.display = 'none'; this.currentPreviewIndex = -1; } else if (this.currentPreviewIndex >= this.files.length) { this.previewFile(this.files.length - 1); } this.renderFileList(); this.updateUI(); this.showMessage('File removed', 'info'); } clearAll() { if (this.files.length === 0) return; if (confirm(`Remove all ${this.files.length} files?`)) { this.files = []; this.currentPreviewIndex = -1; this.pdfData = null; this.convertedFiles = []; this.renderFileList(); this.updateUI(); this.noPreview.style.display = 'flex'; this.presentationPreview.style.display = 'none'; this.showMessage('All files cleared', 'info'); } } updateUI() { this.updateStats(); this.updatePreviewCount(); this.convertBtn.disabled = this.files.length === 0; this.downloadBtn.disabled = this.convertedFiles.length === 0; } updateStats() { const totalFiles = this.files.length; const converted = this.files.filter(f => f.status === 'converted').length; const totalSize = this.files.reduce((sum, file) => sum + file.size, 0); const totalSlides = this.files.reduce((sum, file) => sum + file.slideCount, 0); this.fileCount.textContent = totalFiles; this.convertedCount.textContent = converted; this.totalSize.textContent = this.formatFileSize(totalSize); } updatePreviewCount() { this.previewCount.textContent = this.files.length === 0 ? 'No Files' : `${this.files.length} Presentation${this.files.length !== 1 ? 's' : ''}`; } showLoading(show) { this.loading.style.display = show ? 'block' : 'none'; } showMessage(text, type = 'info') { this.statusMessage.textContent = text; this.statusMessage.className = `status-message status-${type}`; this.statusMessage.style.display = 'block'; setTimeout(() => { this.statusMessage.style.display = 'none'; }, 5000); } formatFileSize(bytes) { if (bytes === 0) return '0 Bytes'; const k = 1024; const sizes = ['Bytes', 'KB', 'MB', 'GB']; const i = Math.floor(Math.log(bytes) / Math.log(k)); return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + ' ' + sizes[i]; } truncateFileName(name, maxLength = 30) { return name.length > maxLength ? name.substring(0, maxLength - 3) + '...' : name; } escapeHtml(text) { const div = document.createElement('div'); div.textContent = text; return div.innerHTML; } } // Initialize the POWERPOINT to PDF Converter let powerpointToPDFConverter; window.addEventListener('DOMContentLoaded', () => { powerpointToPDFConverter = new POWERPOINTtoPDFConverter(); });

Post a Comment

0 Comments