M
E-Agri ERP
Mizoram Digital Agriculture Infrastructure
Govt. of Mizoram Live
Department Admin
Templates
24
Govt + dept presets
Generated · this month
142
Mar 2026 · +21% vs Feb
Scheduled exports
8
Cron + cohort triggers
Distribution lists
12
142 recipients total
Template Gallery
24 preset reports
Click to generate now, schedule recurring, or preview a sample run
Custom Report Builder
Build your own
Pick a source, fields, filters and grouping · live preview updates as you toggle

Live preview

Adjust controls — preview updates instantly
Recent Reports
15 most-recent generated reports
All artefacts hash-signed and retained 7 years per DPDP audit policy
Name Type Generated by Date Size Format Status Actions
Scheduled exports
8 active · cron-driven · delivered via signed email + portal drop
Distribution lists
12 lists · click to view members
Detail
×
`; return new Blob([html], { type: 'application/vnd.ms-excel;charset=utf-8' }); } function buildHtmlReport(report, opts) { opts = opts || {}; const esc = v => String(v==null?'':v).replace(/&/g,'&').replace(//g,'>'); const now = new Date(); const ts = now.toISOString().slice(0,16).replace('T',' ') + ' UTC'; return ` ${esc(report.title)} — MDAI
M
${esc(report.title)}
Mizoram Digital Agriculture Infrastructure · E-Agri ERP
Department of Agriculture
Government of Mizoram
Generated ${esc(ts)}
Report ID: RPT-${Date.now().toString(36).toUpperCase()}
Executive summary — ${esc(report.summary)}
Report period
${esc(opts.dateFrom||'2026-01-01')} → ${esc(opts.dateTo||'2026-03-30')}
Districts
${esc((opts.districts||['All']).join(', ').slice(0,40))}${opts.districts && opts.districts.length>3?'…':''}
Rows
${report.rows.length.toLocaleString('en-IN')}
FRD Reference
FRD v3.0 § Reports
${report.columns.map(c => '').join('')} ${report.rows.map(r => '' + r.map(v => '').join('') + '').join('\n')}
'+esc(c)+'
'+esc(v)+'
Generated by
MDAI E-Agri ERP
Automated · sha256-signed
Reviewed by
Director, Department of Agriculture
Approved by
Principal Secretary (Agri.)
`; } // ── Helpers ── function downloadBlob(blob, filename) { const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = filename; document.body.appendChild(a); a.click(); setTimeout(() => { document.body.removeChild(a); URL.revokeObjectURL(url); }, 1000); } function openInWindow(htmlString, autoprint) { const w = window.open('', '_blank'); if (!w) { alert('Popup blocked — allow popups for this site to view reports.'); return; } w.document.open(); w.document.write(htmlString); w.document.close(); if (autoprint) { w.onload = function() { setTimeout(() => w.print(), 500); }; } } function safeFilename(s) { return s.replace(/[^A-Za-z0-9-]+/g,'_').replace(/_+/g,'_').replace(/^_|_$/g,''); } // ── Public entry: generate(templateId, format, opts) ── function generateReport(templateId, format, opts) { const builder = BUILDERS[templateId]; if (!builder) { window.toast && window.toast('Template '+templateId+' has no data extractor', 'error'); return null; } const report = builder(); const stamp = new Date().toISOString().slice(0,10); const base = `MDAI_${safeFilename(report.title)}_${stamp}`; if (format === 'CSV') { downloadBlob(buildCsv(report), base + '.csv'); window.toast && window.toast('Downloaded ' + base + '.csv', 'success'); } else if (format === 'Excel' || format === 'XLS') { downloadBlob(buildXlsHtml(report), base + '.xls'); window.toast && window.toast('Downloaded ' + base + '.xls', 'success'); } else { // PDF — open print-ready HTML in new window openInWindow(buildHtmlReport(report, opts), false); window.toast && window.toast('Report opened · click "Print / Save as PDF"', 'success'); } return { report, base }; } // Expose window.MDAI_REPORTS = { generate: generateReport, builders: BUILDERS, buildHtmlReport, buildCsv, buildXlsHtml, downloadBlob, openInWindow, }; // Helper used from inline onclick: download an existing Recent row. // Picks a builder by matching the report name (case-insensitive substring) or // by index lookup; falls back to T01. window.downloadRecent = function(name, format) { const t = (Object.entries(BUILDERS).find(([id,fn]) => { const r = fn(); return r.title.toLowerCase() === name.toLowerCase() || name.toLowerCase().includes(r.title.toLowerCase().split(' ')[0].toLowerCase()); }) || ['T01', BUILDERS.T01])[0]; return generateReport(t, format || 'CSV'); }; })();