diff options
| author | dujinkim <dujin.kim@dtsolution.co.kr> | 2025-04-28 02:13:30 +0000 |
|---|---|---|
| committer | dujinkim <dujin.kim@dtsolution.co.kr> | 2025-04-28 02:13:30 +0000 |
| commit | ef4c533ebacc2cdc97e518f30e9a9350004fcdfb (patch) | |
| tree | 345251a3ed0f4429716fa5edaa31024d8f4cb560 /components/form-data/sedp-excel-download.tsx | |
| parent | 9ceed79cf32c896f8a998399bf1b296506b2cd4a (diff) | |
~20250428 작업사항
Diffstat (limited to 'components/form-data/sedp-excel-download.tsx')
| -rw-r--r-- | components/form-data/sedp-excel-download.tsx | 163 |
1 files changed, 163 insertions, 0 deletions
diff --git a/components/form-data/sedp-excel-download.tsx b/components/form-data/sedp-excel-download.tsx new file mode 100644 index 00000000..70f5c46a --- /dev/null +++ b/components/form-data/sedp-excel-download.tsx @@ -0,0 +1,163 @@ +import * as React from "react"; +import { Button } from "@/components/ui/button"; +import { FileDown, Loader } from "lucide-react"; +import { toast } from "sonner"; +import * as ExcelJS from 'exceljs'; + +interface ExcelDownloadProps { + comparisonResults: Array<{ + tagNo: string; + tagDesc: string; + isMatching: boolean; + attributes: Array<{ + key: string; + label: string; + localValue: any; + sedpValue: any; + isMatching: boolean; + uom?: string; + }>; + }>; + formCode: string; + disabled: boolean; +} + +export function ExcelDownload({ comparisonResults, formCode, disabled }: ExcelDownloadProps) { + const [isExporting, setIsExporting] = React.useState(false); + + // Function to generate and download Excel file with differences + const handleExportDifferences = async () => { + try { + setIsExporting(true); + + // Get only items with differences + const itemsWithDifferences = comparisonResults.filter(item => !item.isMatching); + + if (itemsWithDifferences.length === 0) { + toast.info("차이가 없어 다운로드할 내용이 없습니다"); + return; + } + + // Create a new workbook + const workbook = new ExcelJS.Workbook(); + workbook.creator = 'SEDP Compare Tool'; + workbook.created = new Date(); + + // Add a worksheet + const worksheet = workbook.addWorksheet('SEDP Differences'); + + // Add headers + worksheet.columns = [ + { header: 'Tag Number', key: 'tagNo', width: 20 }, + { header: 'Tag Description', key: 'tagDesc', width: 30 }, + { header: 'Attribute', key: 'attribute', width: 25 }, + { header: 'Local Value', key: 'localValue', width: 20 }, + { header: 'SEDP Value', key: 'sedpValue', width: 20 } + ]; + + // Style the header row + const headerRow = worksheet.getRow(1); + headerRow.eachCell((cell) => { + cell.font = { bold: true }; + cell.fill = { + type: 'pattern', + pattern: 'solid', + fgColor: { argb: 'FFE0E0E0' } + }; + cell.border = { + top: { style: 'thin' }, + left: { style: 'thin' }, + bottom: { style: 'thin' }, + right: { style: 'thin' } + }; + }); + + // Add data rows + let rowIndex = 2; + itemsWithDifferences.forEach(item => { + const differences = item.attributes.filter(attr => !attr.isMatching); + + if (differences.length === 0) return; + + differences.forEach(diff => { + const row = worksheet.getRow(rowIndex++); + + // Format local value with UOM + const localDisplay = diff.localValue === null || diff.localValue === undefined || diff.localValue === '' + ? "(empty)" + : diff.uom ? `${diff.localValue} ${diff.uom}` : diff.localValue; + + // SEDP value is displayed as-is + const sedpDisplay = diff.sedpValue === null || diff.sedpValue === undefined || diff.sedpValue === '' + ? "(empty)" + : diff.sedpValue; + + // Set cell values + row.getCell('tagNo').value = item.tagNo; + row.getCell('tagDesc').value = item.tagDesc; + row.getCell('attribute').value = diff.label; + row.getCell('localValue').value = localDisplay; + row.getCell('sedpValue').value = sedpDisplay; + + // Style the row + row.getCell('localValue').font = { color: { argb: 'FFFF0000' } }; // Red for local value + row.getCell('sedpValue').font = { color: { argb: 'FF008000' } }; // Green for SEDP value + + // Add borders + row.eachCell((cell) => { + cell.border = { + top: { style: 'thin' }, + left: { style: 'thin' }, + bottom: { style: 'thin' }, + right: { style: 'thin' } + }; + }); + }); + + // Add a blank row after each tag for better readability + rowIndex++; + }); + + // Generate Excel file + const buffer = await workbook.xlsx.writeBuffer(); + + // Create a Blob from the buffer + const blob = new Blob([buffer], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' }); + + // Create a download link and trigger the download + const url = window.URL.createObjectURL(blob); + const a = document.createElement('a'); + a.href = url; + a.download = `SEDP_Differences_${formCode}_${new Date().toISOString().slice(0, 10)}.xlsx`; + document.body.appendChild(a); + a.click(); + + // Clean up + window.URL.revokeObjectURL(url); + document.body.removeChild(a); + + toast.success("차이점 Excel 다운로드 완료"); + } catch (error) { + console.error("Error exporting to Excel:", error); + toast.error("Excel 다운로드 실패"); + } finally { + setIsExporting(false); + } + }; + + return ( + <Button + variant="secondary" + onClick={handleExportDifferences} + disabled={disabled || isExporting} + className="flex items-center gap-2" + > + {isExporting ? ( + <Loader className="h-4 w-4 animate-spin" /> + ) : ( + <FileDown className="h-4 w-4" /> + )} + 차이점 Excel로 다운로드 + </Button> + ); +}
\ No newline at end of file |
