first commit
This commit is contained in:
commit
367533c02b
171 files changed
+101175
No files matched your search
@@ -0,0 +1,120 @@
|
||||
import ExcelJS from 'exceljs';
|
||||
import type { DashboardReportPayload } from '../types/dashboardReport.ts';
|
||||
|
||||
const na = (value: number | null | undefined): number | string =>
|
||||
value == null || !Number.isFinite(value) ? 'N/A' : value;
|
||||
|
||||
export async function downloadReportExcel(payload: DashboardReportPayload): Promise<void> {
|
||||
const workbook = new ExcelJS.Workbook();
|
||||
workbook.creator = 'Dashboard CPSP';
|
||||
|
||||
const counting = workbook.addWorksheet('Chicken Counting');
|
||||
counting.addRow([
|
||||
'Tanggal',
|
||||
'Hari',
|
||||
'Stok awal',
|
||||
'Mortalitas',
|
||||
'Panen',
|
||||
'Stok akhir',
|
||||
'IoT',
|
||||
'Akurasi %',
|
||||
]);
|
||||
for (const row of payload.counting) {
|
||||
counting.addRow([
|
||||
row.date,
|
||||
row.day,
|
||||
na(row.countBefore),
|
||||
na(row.mortality),
|
||||
na(row.harvest),
|
||||
na(row.countAfter),
|
||||
na(row.iotCount),
|
||||
na(row.accuracy),
|
||||
]);
|
||||
}
|
||||
|
||||
const weight = workbook.addWorksheet('Weight');
|
||||
weight.addRow([
|
||||
'Tanggal',
|
||||
'Hari',
|
||||
'AVG manual',
|
||||
'AVG IoT',
|
||||
'Keseragaman',
|
||||
'Selisih',
|
||||
'Akurasi %',
|
||||
]);
|
||||
for (const row of payload.weight) {
|
||||
weight.addRow([
|
||||
row.date,
|
||||
row.day,
|
||||
na(row.avgManual),
|
||||
na(row.avgIot),
|
||||
na(row.uniformity),
|
||||
na(row.difference),
|
||||
na(row.accuracy),
|
||||
]);
|
||||
}
|
||||
|
||||
const feedInSheet = workbook.addWorksheet('Feed In');
|
||||
feedInSheet.addRow(['Tanggal', 'Manual in', 'IoT in', 'Akurasi in %']);
|
||||
for (const row of payload.feedIn) {
|
||||
feedInSheet.addRow([row.date, na(row.manualIn), na(row.iotIn), na(row.accuracy)]);
|
||||
}
|
||||
|
||||
const feedUseSheet = workbook.addWorksheet('Feed Use');
|
||||
feedUseSheet.addRow(['Tanggal', 'Hari', 'Manual use', 'IoT use', 'Akurasi use %']);
|
||||
for (const row of payload.feedUse) {
|
||||
feedUseSheet.addRow([row.date, row.day, na(row.manualUse), na(row.iotUse), na(row.accuracy)]);
|
||||
}
|
||||
|
||||
const feedOutSheet = workbook.addWorksheet('Feed Out');
|
||||
feedOutSheet.addRow(['Tanggal', 'Manual out', 'IoT out', 'Akurasi out %']);
|
||||
for (const row of payload.feedOut) {
|
||||
feedOutSheet.addRow([row.date, na(row.manualOut), na(row.iotOut), na(row.accuracy)]);
|
||||
}
|
||||
|
||||
const fcrSheet = workbook.addWorksheet('FCR');
|
||||
fcrSheet.addRow(['Hari', 'FCR', 'Total Pakan', 'Bobot IoT', 'Ayam Hidup', 'Total Bobot Panen']);
|
||||
for (const row of payload.fcr) {
|
||||
fcrSheet.addRow([
|
||||
row.day,
|
||||
na(row.iotFcr),
|
||||
na(row.feedTotal),
|
||||
na(row.iotWeight),
|
||||
na(row.chickenLife),
|
||||
na(row.harvestWeightTotal),
|
||||
]);
|
||||
}
|
||||
|
||||
const eefSheet = workbook.addWorksheet('EEF');
|
||||
eefSheet.addRow([
|
||||
'Hari',
|
||||
'EEF',
|
||||
'Persentase Ayam Hidup',
|
||||
'BW Rata-rata Panen',
|
||||
'Umur Rata-rata Panen',
|
||||
'FCR',
|
||||
]);
|
||||
for (const row of payload.eef) {
|
||||
eefSheet.addRow([
|
||||
row.day,
|
||||
na(row.iotEef),
|
||||
na(row.chickenLifePercentage),
|
||||
na(row.iotAverageHarvestBw),
|
||||
na(row.iotAverageDayWeight),
|
||||
na(row.iotFcr),
|
||||
]);
|
||||
}
|
||||
|
||||
const buffer = await workbook.xlsx.writeBuffer();
|
||||
const blob = new Blob([buffer], {
|
||||
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
||||
});
|
||||
const period =
|
||||
payload.reportType === 'end_cycle' ? 'Akhir-Siklus' : `Harian-Hari-${payload.upToDay}`;
|
||||
const url = URL.createObjectURL(blob);
|
||||
const anchor = document.createElement('a');
|
||||
anchor.href = url;
|
||||
anchor.download = `Laporan-${period}-${payload.area}-${payload.kandangName}-${payload.cycleStart}_sd_${payload.cycleEnd}.xlsx`;
|
||||
anchor.click();
|
||||
URL.revokeObjectURL(url);
|
||||
}
|
||||
Reference in new issue
Block a user