Business Proposal Generator

Business Proposal Generator

Create a professional proposal in minutes.

Client Information

Your Information

Project Scope

Pricing Breakdown

Total: $0.00

${getValue('proposedSolution')}

Deliverables:

${getValue('deliverables')}


Pricing:

${pricingData.map(i => ``).join('')}
ItemQtyCost
${i.desc}${i.qty}$${(i.qty * i.cost).toFixed(2)}
Total:$${totalPriceEl.textContent}
`; }; // --- PDF Download Logic --- downloadPdfBtn.addEventListener('click', () => { if (typeof window.jspdf === 'undefined') { return; } const { jsPDF } = window.jspdf; const doc = new jsPDF({ orientation: 'p', unit: 'pt', format: 'letter' }); const getValue = id => document.getElementById(id).value; const page = { width: doc.internal.pageSize.getWidth(), margin: 40 }; page.contentWidth = page.width - page.margin * 2; let y = page.margin; // Header doc.setFont('helvetica', 'bold'); doc.setFontSize(24); doc.text('Business Proposal', page.width / 2, y, { align: 'center' }); y += 40; // Info Blocks doc.setFontSize(10); doc.setFont('helvetica', 'bold'); doc.text('PREPARED FOR:', page.margin, y); doc.text('PREPARED BY:', page.width / 2, y); y += 15; doc.setFont('helvetica', 'normal'); doc.text(getValue('clientCompany'), page.margin, y); doc.text(getValue('providerName'), page.width / 2, y); y += 12; doc.text(getValue('clientName'), page.margin, y); doc.text(getValue('providerContact'), page.width / 2, y); y += 12; doc.text(getValue('clientContact'), page.margin, y); doc.text(`Date: ${getValue('proposalDate')}`, page.width / 2, y); y += 50; // Section Helper const addSection = (title, content) => { if (y > doc.internal.pageSize.getHeight() - 100) { doc.addPage(); y = page.margin; } doc.setFontSize(14); doc.setFont('helvetica', 'bold'); doc.text(title, page.margin, y); doc.setLineWidth(1.5); doc.line(page.margin, y + 3, page.margin + 80, y + 3); y += 25; doc.setFontSize(11); doc.setFont('helvetica', 'normal'); const textLines = doc.splitTextToSize(content, page.contentWidth); doc.text(textLines, page.margin, y); y += textLines.length * 12 + 20; }; addSection('Problem Statement', getValue('problemStatement')); addSection('Proposed Solution', getValue('proposedSolution')); addSection('Scope of Work & Deliverables', getValue('deliverables')); // Pricing Section if (y > doc.internal.pageSize.getHeight() - 150) { doc.addPage(); y = page.margin; } doc.setFontSize(14); doc.setFont('helvetica', 'bold'); doc.text('Investment', page.margin, y); doc.setLineWidth(1.5); doc.line(page.margin, y + 3, page.margin + 80, y + 3); y += 25; // Pricing Table Header doc.setFontSize(10); doc.setFont('helvetica', 'bold'); doc.text('DESCRIPTION', page.margin, y); doc.text('QTY', page.margin + 300, y); doc.text('UNIT COST', page.margin + 360, y); doc.text('TOTAL', page.width - page.margin, y, { align: 'right' }); y += 15; // Pricing Table Rows doc.setFontSize(10); doc.setFont('helvetica', 'normal'); document.querySelectorAll('#pricingItems > div').forEach(item => { const desc = item.querySelector('.price-desc').value; const qty = parseFloat(item.querySelector('.price-qty').value) || 0; const cost = parseFloat(item.querySelector('.price-cost').value) || 0; doc.text(desc, page.margin, y); doc.text(qty.toString(), page.margin + 300, y); doc.text(`$${cost.toFixed(2)}`, page.margin + 360, y); doc.text(`$${(qty * cost).toFixed(2)}`, page.width - page.margin, y, { align: 'right' }); y += 15; }); // Total doc.setLineWidth(1); doc.line(page.margin + 350, y, page.width - page.margin, y); y += 15; doc.setFontSize(12); doc.setFont('helvetica', 'bold'); doc.text('Total Investment:', page.margin + 350, y); doc.text(`$${totalPriceEl.textContent}`, page.width - page.margin, y, { align: 'right' }); doc.save(`Proposal-for-${getValue('clientCompany') || 'Client'}.pdf`); }); // --- Initial Setup --- document.getElementById('proposalDate').valueAsDate = new Date(); addPricingItem(); switchTab('client'); });
Scroll to Top