diff --git a/src/components/pages/report/production-result/export/ProductionResultExportXLSX.tsx b/src/components/pages/report/production-result/export/ProductionResultExportXLSX.tsx index e69de29b..af0380c0 100644 --- a/src/components/pages/report/production-result/export/ProductionResultExportXLSX.tsx +++ b/src/components/pages/report/production-result/export/ProductionResultExportXLSX.tsx @@ -0,0 +1,135 @@ +'use client'; + +import ExcelJS from 'exceljs'; +import { formatNumber } from '@/lib/helper'; +import { ProductionResult } from '@/types/api/report/production-result'; + +interface ProductionResultExportExcelParams { + data: ProductionResult[]; + period?: string; +} + +export const generateProductionResultExcel = async ( + params: ProductionResultExportExcelParams +): Promise => { + if (!params.data || params.data.length === 0) { + return; + } + + const workbook = new ExcelJS.Workbook(); + + // ===== PRODUCTION RESULT WORKSHEET ===== + const columns = [ + { header: 'No', key: 'no', width: 6 }, + { header: 'Project Flock', key: 'projectFlockName', width: 25 }, + { + header: 'Category', + key: 'projectFlockCategory', + width: 18, + }, + { header: 'Kandang', key: 'kandangName', width: 18 }, + { header: 'Week of Age (WOA)', key: 'woa', width: 20 }, + { header: 'Body Weight (BW)', key: 'bw', width: 18 }, + { header: 'Body Weight (Std BW)', key: 'stdBw', width: 22 }, + { header: 'Uniformity (%)', key: 'uniformity', width: 16 }, + { header: 'Uniformity Std (%)', key: 'stdUniformity', width: 20 }, + { header: 'Depletion Cumulative', key: 'depKum', width: 22 }, + { header: 'Depletion Standard', key: 'depStd', width: 20 }, + { header: 'Telur Utuh', key: 'butiranUtuh', width: 14 }, + { header: 'Telur Putih', key: 'butiranPutih', width: 14 }, + { header: 'Telur Retak', key: 'butiranRetak', width: 14 }, + { header: 'Telur Pecah', key: 'butiranPecah', width: 14 }, + { header: 'Jumlah Telur', key: 'butiranJumlah', width: 16 }, + { header: 'Total Telur', key: 'totalButir', width: 14 }, + { header: 'Utuh (Kg)', key: 'kgUtuh', width: 12 }, + { header: 'Putih (Kg)', key: 'kgPutih', width: 12 }, + { header: 'Retak (Kg)', key: 'kgRetak', width: 12 }, + { header: 'Pecah (Kg)', key: 'kgPecah', width: 12 }, + { header: 'Jumlah (Kg)', key: 'kgJumlah', width: 14 }, + { header: 'Total Weight (Kg)', key: 'totalKg', width: 20 }, + { header: 'Utuh (%)', key: 'persenUtuh', width: 12 }, + { header: 'Putih (%)', key: 'persenPutih', width: 12 }, + { header: 'Retak (%)', key: 'persenRetak', width: 12 }, + { header: 'Pecah (%)', key: 'persenPecah', width: 12 }, + { header: 'Hen Day (HD)', key: 'hd', width: 15 }, + { header: 'Hen Day Std (HD Std)', key: 'hdStd', width: 22 }, + { header: 'Feed Intake (FI)', key: 'fi', width: 18 }, + { header: 'Feed Intake Std (FI Std)', key: 'fiStd', width: 25 }, + { header: 'Egg Mass (EM)', key: 'em', width: 16 }, + { header: 'Egg Mass Std (EM Std)', key: 'emStd', width: 23 }, + { header: 'Egg Weight (EW)', key: 'ew', width: 18 }, + { header: 'Egg Weight Std (EW Std)', key: 'ewStd', width: 25 }, + { header: 'Feed Conversion Ratio (FCR)', key: 'fcr', width: 30 }, + { + header: 'Feed Conversion Ratio Std (FCR Std)', + key: 'fcrStd', + width: 35, + }, + { header: 'Hen House (HH)', key: 'hh', width: 18 }, + { header: 'Hen House Std (HH Std)', key: 'hhStd', width: 25 }, + ]; + + const worksheet = workbook.addWorksheet('Production Result'); + worksheet.columns = columns; + + // Add data rows + params.data.forEach((item: ProductionResult, index: number) => { + worksheet.addRow({ + no: index + 1, + projectFlockName: item.project_flock?.name || '', + projectFlockCategory: item.project_flock?.category || '', + kandangName: item.project_flock?.kandang?.name || '', + woa: formatNumber(item.woa || 0), + bw: formatNumber(item.bw || 0), + stdBw: formatNumber(item.std_bw || 0), + uniformity: formatNumber(item.uniformity || 0), + stdUniformity: item.std_uniformity || '', + depKum: formatNumber(item.dep_kum || 0), + depStd: formatNumber(item.dep_std || 0), + butiranUtuh: formatNumber(item.butiran_utuh || 0), + butiranPutih: formatNumber(item.butiran_putih || 0), + butiranRetak: formatNumber(item.butiran_retak || 0), + butiranPecah: formatNumber(item.butiran_pecah || 0), + butiranJumlah: formatNumber(item.butiran_jumlah || 0), + totalButir: formatNumber(item.total_butir || 0), + kgUtuh: formatNumber(item.kg_utuh || 0), + kgPutih: formatNumber(item.kg_putih || 0), + kgRetak: formatNumber(item.kg_retak || 0), + kgPecah: formatNumber(item.kg_pecah || 0), + kgJumlah: formatNumber(item.kg_jumlah || 0), + totalKg: formatNumber(item.total_kg || 0), + persenUtuh: formatNumber(item.persen_utuh || 0), + persenPutih: formatNumber(item.persen_putih || 0), + persenRetak: formatNumber(item.persen_retak || 0), + persenPecah: formatNumber(item.persen_pecah || 0), + hd: formatNumber(item.hd || 0), + hdStd: formatNumber(item.hd_std || 0), + fi: formatNumber(item.fi || 0), + fiStd: formatNumber(item.fi_std || 0), + em: formatNumber(item.em || 0), + emStd: formatNumber(item.em_std || 0), + ew: formatNumber(item.ew || 0), + ewStd: formatNumber(item.ew_std || 0), + fcr: formatNumber(item.fcr || 0), + fcrStd: formatNumber(item.fcr_std || 0), + hh: formatNumber(item.hh || 0), + hhStd: formatNumber(item.hh_std || 0), + }); + }); + + const currentDate = new Date().toISOString().split('T')[0]; + const filename = params.period + ? `laporan-hasil-produksi-${params.period}.xlsx` + : `laporan-hasil-produksi-${currentDate}.xlsx`; + + const buffer = await workbook.xlsx.writeBuffer(); + const blob = new Blob([buffer], { + type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', + }); + const url = window.URL.createObjectURL(blob); + const link = document.createElement('a'); + link.href = url; + link.download = filename; + link.click(); + window.URL.revokeObjectURL(url); +};