CV Formatting Tool

CV Formatting Tool

Enter your details to generate a professional curriculum vitae.

Personal Details

Professional Summary

Work Experience

Education

Skills

${exp.desc.replace(/\n/g, '
')}

`; }); previewHTML += `
`; } if(currentCVData.education.length > 0) { previewHTML += `

Education

`; currentCVData.education.forEach(edu => { previewHTML += `

${edu.degree}

${edu.school} (${edu.dates})
`; }); previewHTML += `
`; } if(currentCVData.skills.length > 0) { previewHTML += `

Skills

${currentCVData.skills.join(', ')}

`; } selectors.cvPreview.innerHTML = previewHTML; selectors.resultsDashboard.classList.remove('hidden'); selectors.resultsDashboard.scrollIntoView({ behavior: 'smooth' }); }; // --- PDF Generation --- const downloadPDF = () => { if (!currentCVData.name) return; const { jsPDF } = window.jspdf; const doc = new jsPDF({ orientation: 'p', unit: 'mm', format: 'a4' }); const margin = 15; const pageWidth = doc.internal.pageSize.getWidth(); const contentWidth = pageWidth - margin * 2; let y = margin; // Header doc.setFont('helvetica', 'bold'); doc.setFontSize(24); doc.setTextColor('#1e3a8a'); // Blue 800 doc.text(currentCVData.name, pageWidth / 2, y, { align: 'center' }); y += 8; doc.setFont('helvetica', 'normal'); doc.setFontSize(10); doc.setTextColor('#4b5563'); // Gray 600 const contactInfo = [currentCVData.phone, currentCVData.email, currentCVData.linkedin].filter(Boolean).join(' • '); doc.text(contactInfo, pageWidth / 2, y, { align: 'center' }); y += 10; const addSection = (title, contentFn) => { if (y > 260) { doc.addPage(); y = margin; } doc.setFont('helvetica', 'bold'); doc.setFontSize(14); doc.setTextColor('#1e3a8a'); doc.text(title.toUpperCase(), margin, y); doc.setDrawColor('#93c5fd'); // Blue 300 doc.setLineWidth(0.5); doc.line(margin, y + 2, pageWidth - margin, y + 2); y += 10; contentFn(); }; // Summary if (currentCVData.summary) { addSection('Summary', () => { doc.setFont('helvetica', 'normal'); doc.setFontSize(10.5); doc.setTextColor('#374151'); const lines = doc.splitTextToSize(currentCVData.summary, contentWidth); doc.text(lines, margin, y); y += (lines.length * 5) + 5; }); } // Experience if (currentCVData.experience.length > 0) { addSection('Experience', () => { currentCVData.experience.forEach(exp => { if (y > 260) { doc.addPage(); y = margin; } doc.setFont('helvetica', 'bold'); doc.setFontSize(11); doc.setTextColor('#1f2937'); doc.text(exp.title, margin, y); doc.setFont('helvetica', 'normal'); doc.setFontSize(10); doc.setTextColor('#4b5563'); doc.text(exp.company, margin, y + 5); doc.text(exp.dates, pageWidth - margin, y + 5, { align: 'right' }); doc.setFontSize(10); doc.setTextColor('#374151'); const descLines = doc.splitTextToSize(`• ${exp.desc.replace(/\n/g, '\n• ')}`, contentWidth-5); doc.text(descLines, margin + 5, y + 11); y += 12 + (descLines.length * 4.5); }); }); } // Education if (currentCVData.education.length > 0) { addSection('Education', () => { currentCVData.education.forEach(edu => { if (y > 250) { doc.addPage(); y = margin; } doc.setFont('helvetica', 'bold'); doc.setFontSize(11); doc.setTextColor('#1f2937'); doc.text(edu.degree, margin, y); doc.setFont('helvetica', 'normal'); doc.setFontSize(10); doc.setTextColor('#4b5563'); doc.text(edu.school, margin, y + 5); doc.text(edu.dates, pageWidth - margin, y + 5, { align: 'right' }); y += 12; }); }); } // Skills if(currentCVData.skills.length > 0) { addSection('Skills', () => { doc.setFont('helvetica', 'normal'); doc.setFontSize(10.5); doc.setTextColor('#374151'); doc.text(currentCVData.skills.join(', '), margin, y); y+= 10; }); } doc.save(`CV_${currentCVData.name.replace(' ', '_')}.pdf`); }; // --- Initial Setup & Event Listeners --- addExperience(); addEducation(); selectors.addExperienceBtn.addEventListener('click', addExperience); selectors.addEducationBtn.addEventListener('click', addEducation); selectors.generateBtn.addEventListener('click', generateCV); selectors.downloadPdfBtn.addEventListener('click', downloadPDF); });
Scroll to Top