Net Profit
${formatCurrency(netProfit)}
`;
}
function renderChart() {
if(chartInstance) chartInstance.destroy();
chartInstance = new Chart(elements.chartCanvas, {
type: 'bar',
data: {
labels: reportData.map(r => r.month),
datasets: [
{ label: 'Revenue', data: reportData.map(r => r.revenue), backgroundColor: 'rgba(59, 130, 246, 0.7)' },
{ label: 'Expenses', data: reportData.map(r => r.expenses), backgroundColor: 'rgba(239, 68, 68, 0.7)' }
]
},
options: { responsive: true, maintainAspectRatio: false }
});
}
// --- PDF GENERATION ---
async function generatePDF() {
const { jsPDF } = window.jspdf;
const doc = new jsPDF({ orientation: 'p', unit: 'pt', format: 'a4' });
// 1. Capture chart as an image
const chartCanvas = await html2canvas(elements.chartCanvas, { scale: 2 });
const chartImage = chartCanvas.toDataURL('image/png');
// 2. Add text content
doc.setFontSize(22);
doc.text("Monthly Financial Report", 40, 60);
doc.setFontSize(12);
doc.setTextColor(100);
doc.text("This document summarizes the financial performance based on the provided data.", 40, 80);
// 3. Add table using jspdf-autotable
const tableHead = [['Month', 'Revenue', 'Expenses', 'Profit']];
const tableBody = reportData.map(row => [
row.month,
formatCurrency(row.revenue),
formatCurrency(row.expenses),
formatCurrency(row.revenue - row.expenses)
]);
doc.autoTable({
head: tableHead,
body: tableBody,
startY: 100,
theme: 'grid',
headStyles: { fillColor: [22, 163, 74] }
});
// 4. Add chart image
const finalY = doc.lastAutoTable.finalY; // Get position after table
doc.addPage();
doc.setFontSize(18);
doc.text("Performance Chart", 40, 60);
// A4 page is 595pt wide. Let's make image 515pt wide (with 40pt margins)
const imgWidth = 515;
const imgHeight = chartCanvas.height * imgWidth / chartCanvas.width;
doc.addImage(chartImage, 'PNG', 40, 80, imgWidth, imgHeight);
// 5. Save the PDF
doc.save('Flutter_Report.pdf');
}
initialize();
});