Solar & Renewable Energy Investment Analyzer

Project & System Details

Investment Costs & Incentives

Energy Value & Revenue

Operational Costs & Financial Parameters

Analysis Results

Please complete all previous sections and click "Analyze Investment".

First Year Net Savings: ${sreia_formatCurrency(sreia_analysisData.results.firstYearNetSavings)}

Simple Payback Period: ${sreia_analysisData.results.simplePaybackPeriod}

Total Lifetime Net Savings: ${sreia_formatCurrency(sreia_analysisData.results.totalLifetimeNetSavings)}

Net Present Value (NPV) @ ${(inputs.discountRatePercent*100).toFixed(1)}%: ${sreia_formatCurrency(sreia_analysisData.results.npv)}

Internal Rate of Return (IRR): ${sreia_analysisData.results.irr}

`; dlButton.style.display = 'block'; // Show PDF download button resTabLink.disabled = false; // Enable results tab resTabLink.click(); // Switch to results tab } } // Function to generate and download PDF of the analysis window.sreia_downloadPDF = function() { const { jsPDF } = window.jspdf; // Destructure jsPDF from the global jspdf object // Ensure jsPDF is loaded and analysis data is available if (!jsPDF || !sreia_analysisData.inputs || Object.keys(sreia_analysisData.inputs).length === 0) { alert("PDF library not loaded or no data to export. Please analyze the investment first."); return; } const doc = new jsPDF(); // Create new jsPDF instance let yPos = 20; // Initial Y position for text const lineHeight = 7; const indent = 5; const pageMargin = 15; const pageWidth = doc.internal.pageSize.getWidth(); const usableWidth = pageWidth - 2 * pageMargin; // PDF Title doc.setFontSize(18); doc.setTextColor(26, 95, 122); // #1a5f7a doc.text("Solar & Renewable Energy Investment Analysis", pageWidth / 2, yPos, { align: 'center' }); yPos += lineHeight * 2.5; // Helper function to add a section to the PDF function addSection(title, dataObj, isList = false) { // Check if new page is needed before adding section title if (yPos > doc.internal.pageSize.getHeight() - pageMargin - (Object.keys(dataObj).length * lineHeight * 1.2) - (lineHeight*2.5) ) { doc.addPage(); yPos = pageMargin; } doc.setFontSize(13); doc.setFont(undefined, 'bold'); doc.setTextColor(0, 121, 145); // #007991 doc.text(title, pageMargin, yPos); yPos += lineHeight * 1.5; doc.setFontSize(10); doc.setFont(undefined, 'normal'); doc.setTextColor(51,51,51); // #333 if (isList) { // For list items like cash flows (array of strings) dataObj.forEach(item => { if (yPos > doc.internal.pageSize.getHeight() - pageMargin - lineHeight) { doc.addPage(); yPos = pageMargin; } doc.text(item, pageMargin + indent, yPos); yPos += lineHeight; }); } else { // For key-value pairs (object) for (const [key, value] of Object.entries(dataObj)) { if (yPos > doc.internal.pageSize.getHeight() - pageMargin - lineHeight) { doc.addPage(); yPos = pageMargin; } // Format key for better readability (e.g., systemSizeKw -> System Size Kw) let formattedKey = key.replace(/([A-Z])/g, ' $1').replace(/^./, str => str.toUpperCase()); // Format value based on its type or key name let valStr = String(value); // Default to string if (typeof value === 'number') { if (key.toLowerCase().includes('rate') || key.toLowerCase().includes('percent') || key === 'taxCreditPercent') { valStr = value.toFixed(2) + '%'; } else if (key.toLowerCase().includes('price') || key.toLowerCase().includes('cost') || key.toLowerCase().includes('value') || key.toLowerCase().includes('savings') || key.toLowerCase().includes('npv') || key === 'taxCreditFixedAmount' || key === 'upfrontRebates') { valStr = sreia_formatCurrency(value); // Use the corrected currency formatter } else { valStr = value.toLocaleString(); // Default number formatting } } else if (key === 'irr' || key === 'simplePaybackPeriod') { valStr = String(value); // Already formatted string } // Skip displaying certain inputs if not relevant (e.g., fixed amount if percent was chosen) if (key === 'taxCreditPercent' && sreia_analysisData.inputs.taxCreditType === 'fixed') continue; if (key === 'taxCreditFixedAmount' && sreia_analysisData.inputs.taxCreditType === 'percent') continue; doc.text(`${formattedKey}:`, pageMargin + indent, yPos); doc.text(valStr, pageMargin + indent + 85, yPos, {align: 'left', maxWidth: usableWidth - (indent + 85)}); yPos += lineHeight * 1.1; // Line spacing } } yPos += lineHeight * 0.5; // Extra space after section } // Prepare input summary data for PDF, ensuring correct formatting const inputSummaryForPdf = { "System Size (kW)": sreia_analysisData.inputs.systemSizeKw, "Initial Annual Production (kWh)": sreia_analysisData.inputs.annualProductionKwh, "Degradation Rate": (sreia_analysisData.inputs.degradationRate * 100), // Pass as number for formatting "Project Lifespan (Years)": sreia_analysisData.inputs.projectLifespanYears, "Total Upfront Cost": sreia_analysisData.inputs.upfrontCost, "Upfront Rebates": sreia_analysisData.inputs.upfrontRebates, "Tax Credit Type": sreia_analysisData.inputs.taxCreditType === 'percent' ? `Percent (${sreia_analysisData.inputs.taxCreditPercent.toFixed(1)}%)` : `Fixed (${sreia_formatCurrency(sreia_analysisData.inputs.taxCreditFixedAmount)})`, "Calculated Tax Credit Amount": sreia_analysisData.inputs.taxCreditValue, "Current Electricity Price ($/kWh)": sreia_analysisData.inputs.currentElectricityPrice, // Pass as number "Price Escalation Rate": (sreia_analysisData.inputs.priceEscalationPercent * 100), "Self-Consumption": (sreia_analysisData.inputs.selfConsumptionPercent * 100), "Export Rate ($/kWh)": sreia_analysisData.inputs.exportRate, "Initial Annual O&M Cost": sreia_analysisData.inputs.annualOmCost, "O&M Escalation Rate": (sreia_analysisData.inputs.omEscalationPercent * 100), "Discount Rate": (sreia_analysisData.inputs.discountRatePercent * 100) }; addSection("Input Parameters Summary", inputSummaryForPdf); // Prepare results summary for PDF const resultsSummaryForPdf = { "Net Initial Investment": sreia_analysisData.results.netInitialInvestment, "First Year Net Savings": sreia_analysisData.results.firstYearNetSavings, "Simple Payback Period": sreia_analysisData.results.simplePaybackPeriod, // Already a string "Total Lifetime Net Savings": sreia_analysisData.results.totalLifetimeNetSavings, "Net Present Value (NPV)": sreia_analysisData.results.npv, "Internal Rate of Return (IRR)": sreia_analysisData.results.irr // Already a string }; addSection("Key Financial Indicators", resultsSummaryForPdf); // Add a sample of annual cash flows to the PDF let cashFlowSampleForPdf = ["Year | Production (kWh) | Benefit ($) | O&M ($) | Net CF ($) | Cumulative CF ($)"]; let tempCumulativeCF_pdf = -sreia_analysisData.results.netInitialInvestment; // Start with initial investment // Header for cash flow table cashFlowSampleForPdf.push(`0 | --- | --- | --- | ${sreia_formatCurrency(-sreia_analysisData.results.netInitialInvestment)} | ${sreia_formatCurrency(tempCumulativeCF_pdf)}`); const yearsToShowInPdf = Math.min(sreia_analysisData.annual_cash_flows.length, 5); // Show first 5 years or less for(let i = 0; i < yearsToShowInPdf; i++) { const cf = sreia_analysisData.annual_cash_flows[i]; tempCumulativeCF_pdf += cf.netAnnualCashFlow; cashFlowSampleForPdf.push( `${cf.year} | ` + `${cf.energyProduction.toFixed(0)} | ` + `${sreia_formatCurrency(cf.totalAnnualBenefit)} | ` + `${sreia_formatCurrency(cf.omCosts)} | ` + `${sreia_formatCurrency(cf.netAnnualCashFlow)} | ` + `${sreia_formatCurrency(tempCumulativeCF_pdf)}` ); } // If more than 5 years, add ellipsis and the last year's data if (sreia_analysisData.annual_cash_flows.length > 5) { cashFlowSampleForPdf.push("..."); // Ellipsis to indicate skipped years const lastCf = sreia_analysisData.annual_cash_flows[sreia_analysisData.annual_cash_flows.length - 1]; // Recalculate cumulative CF for the last year shown in PDF (which is the actual last year of project) tempCumulativeCF_pdf = -sreia_analysisData.results.netInitialInvestment; // Reset sreia_analysisData.annual_cash_flows.forEach(cf_val => tempCumulativeCF_pdf += cf_val.netAnnualCashFlow); // Sum all net CFs cashFlowSampleForPdf.push( `${lastCf.year} | ` + `${lastCf.energyProduction.toFixed(0)} | ` + `${sreia_formatCurrency(lastCf.totalAnnualBenefit)} | ` + `${sreia_formatCurrency(lastCf.omCosts)} | ` + `${sreia_formatCurrency(lastCf.netAnnualCashFlow)} | ` + `${sreia_formatCurrency(tempCumulativeCF_pdf)}` // This is the total lifetime net savings ); } // Check if new page is needed before adding the cash flow table if (yPos > doc.internal.pageSize.getHeight() - pageMargin - (cashFlowSampleForPdf.length * lineHeight) - (lineHeight*2.5) ) { doc.addPage(); yPos = pageMargin; } doc.setFont(undefined,'normal'); // Reset font style doc.setFontSize(8); // Use smaller font for the table-like data addSection("Annual Cash Flow Summary (Sample)", cashFlowSampleForPdf, true); // True for isList doc.save('Solar_Investment_Analysis.pdf'); // Save the PDF }
Scroll to Top