Formal Report Generator (e.g., Annual Report, Project Report)

Formal Report Generator

Formal Report Generator

1. Report Metadata

2. Report Sections & Content

Current Report Flow

    Start by adding an Introduction or Background section.

3. Data Appendix (Tables/Metrics)

Key Metrics (for PDF Appendix)

    Add key metrics (e.g., financial KPIs, survey results).

Start by adding an Introduction or Background section.

'; return; } sections.forEach((item, index) => { const li = document.createElement('li'); li.className = 'frg-list-item'; li.innerHTML = ` ${index + 1}. ${item.title} (${item.content.substring(0, 50)}...) `; li.querySelector('button').addEventListener('click', () => removeSection(item.id)); sectionList.appendChild(li); }); } function addSection() { const title = sectionNameInput.value.trim(); const content = sectionContentTextarea.value.trim(); if (!title || !content) { alert("Please enter both a Section Title and Content."); return; } sections.push({ id: generateId(), title, content }); renderSections(); // Clear form sectionNameInput.value = ''; sectionContentTextarea.value = ''; sectionNameInput.focus(); } function removeSection(id) { sections = sections.filter(item => item.id !== id); renderSections(); } // --- Metrics Management --- function renderMetrics() { metricList.innerHTML = ''; if (metrics.length === 0) { metricList.innerHTML = '

Add key metrics (e.g., financial KPIs, survey results).

'; return; } metrics.forEach((item) => { const li = document.createElement('li'); li.className = 'frg-list-item'; li.innerHTML = ` ${item.name}: ${item.value} `; li.querySelector('button').addEventListener('click', () => removeMetric(item.id)); metricList.appendChild(li); }); } function addMetric() { const name = metricNameInput.value.trim(); const value = metricValueInput.value.trim(); if (!name || !value) { alert("Please enter both a Metric Name and a Value."); return; } metrics.push({ id: generateId(), name, value }); renderMetrics(); // Clear form metricNameInput.value = ''; metricValueInput.value = ''; metricNameInput.focus(); } function removeMetric(id) { metrics = metrics.filter(item => item.id !== id); renderMetrics(); } // --- PDF Generation (Ensured functionality) --- function downloadPDF() { if (typeof window.jspdf === 'undefined' || typeof window.jspdf.jsPDF === 'undefined') { alert('Error: jsPDF library loaded.'); return; } const { jsPDF } = window.jspdf; const doc = new jsPDF('portrait', 'pt', 'a4'); const margin = 40; const pageWidth = doc.internal.pageSize.getWidth(); let currentY = margin; // --- Helper function to add structured text sections --- function addTextSection(title, content, startY) { const estimatedHeight = 15 + (content.split('\n').length * 12) + 10; if (startY + estimatedHeight > doc.internal.pageSize.getHeight() - margin) { doc.addPage(); startY = margin; } doc.setFontSize(12); doc.setFont('helvetica', 'bold'); doc.setTextColor(14, 165, 233); // sky-500 doc.text(title, margin, startY); doc.setFontSize(10); doc.setFont('helvetica', 'normal'); doc.setTextColor(51, 65, 85); const lines = doc.splitTextToSize(content || 'N/A', pageWidth - margin * 2); doc.text(lines, margin, startY + 15); return startY + 15 + lines.length * 12 + 10; } // --- Header --- doc.setFontSize(24); doc.setFont('helvetica', 'bold'); doc.setTextColor(3, 105, 161); // sky-700 doc.text(reportTitleInput.value || 'FORMAL REPORT', pageWidth / 2, currentY, { align: 'center' }); currentY += 15; doc.setFontSize(10); doc.setFont('helvetica', 'normal'); doc.text(`Prepared By: ${authorInput.value || 'N/A'} | Client: ${clientInput.value || 'N/A'}`, pageWidth / 2, currentY, { align: 'center' }); currentY += 12; doc.text(`Date Issued: ${dateInput.value || 'N/A'}`, pageWidth / 2, currentY, { align: 'center' }); currentY += 30; // --- Section 1: Executive Summary --- currentY = addTextSection("1. Executive Summary", executiveSummaryTextarea.value, currentY); // --- Section 2: Narrative Sections --- doc.setFontSize(14); doc.setFont('helvetica', 'bold'); doc.setTextColor(14, 165, 233); doc.text("2. Report Body", margin, currentY); currentY += 15; sections.forEach((section, index) => { doc.setFontSize(12); doc.setFont('helvetica', 'bold'); doc.setTextColor(30, 41, 59); // slate-800 doc.text(`2.${index + 1}. ${section.title}`, margin, currentY); currentY += 15; doc.setFontSize(10); doc.setFont('helvetica', 'normal'); doc.setTextColor(51, 65, 85); const lines = doc.splitTextToSize(section.content, pageWidth - margin * 2); // Check for page break const estimatedHeight = lines.length * 12 + 15; if (currentY + estimatedHeight > doc.internal.pageSize.getHeight() - margin) { doc.addPage(); currentY = margin; } doc.text(lines, margin, currentY); currentY += lines.length * 12 + 10; }); // --- Section 3: Data Appendix --- if (metrics.length > 0) { doc.setFontSize(14); doc.setFont('helvetica', 'bold'); doc.setTextColor(14, 165, 233); doc.text("3. Data Appendix (Key Metrics)", margin, currentY); currentY += 15; const metricTableData = metrics.map(m => [m.name, m.value]); doc.autoTable({ startY: currentY, body: metricTableData, theme: 'striped', headStyles: { fillColor: [59, 130, 246] }, styles: { fontSize: 10, minCellHeight: 12 }, columnStyles: { 0: { fontStyle: 'bold', fillColor: [240, 249, 255], cellWidth: 150 } }, margin: { left: margin, right: pageWidth / 2 } }); } doc.save('formal-report.pdf'); } // --- Event Listeners and Initial Load --- addSectionBtn.addEventListener('click', addSection); addMetricBtn.addEventListener('click', addMetric); sectionList.addEventListener('click', (e) => { if (e.target.dataset.type === 'section') removeSection(e.target.dataset.id); }); metricList.addEventListener('click', (e) => { if (e.target.dataset.type === 'metric') removeMetric(e.target.dataset.id); }); pdfBtn.addEventListener('click', downloadPDF); // Set default date dateInput.value = new Date().toISOString().split('T')[0]; // Sample Data sections.push({ id: generateId(), title: 'Introduction', content: 'This report summarizes the operational performance of the Q3 project cycle, focusing on the deployment metrics and internal resource consumption from July 1 to September 30.' }); metrics.push({ id: generateId(), name: 'Project Completion Rate', value: '92%' }); metrics.push({ id: generateId(), name: 'Total Revenue Lift', value: '$45,000 USD' }); renderSections(); renderMetrics(); });
Scroll to Top