summaryrefslogtreecommitdiff
path: root/components/form-data-plant/sedp-excel-download.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'components/form-data-plant/sedp-excel-download.tsx')
-rw-r--r--components/form-data-plant/sedp-excel-download.tsx259
1 files changed, 259 insertions, 0 deletions
diff --git a/components/form-data-plant/sedp-excel-download.tsx b/components/form-data-plant/sedp-excel-download.tsx
new file mode 100644
index 00000000..36be4847
--- /dev/null
+++ b/components/form-data-plant/sedp-excel-download.tsx
@@ -0,0 +1,259 @@
+import * as React from "react";
+import { useParams } from "next/navigation";
+import { useTranslation } from "@/i18n/client";
+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;
+ }>;
+ }>;
+ missingTags: {
+ localOnly: Array<{ tagNo: string; tagDesc: string }>;
+ sedpOnly: Array<{ tagNo: string; tagDesc: string }>;
+ };
+ formCode: string;
+ disabled: boolean;
+}
+
+export function ExcelDownload({ comparisonResults, missingTags, formCode, disabled }: ExcelDownloadProps) {
+ const [isExporting, setIsExporting] = React.useState(false);
+ const params = useParams();
+ const lng = (params?.lng as string) || "ko";
+ const { t } = useTranslation(lng, "engineering");
+
+ // 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);
+ const hasMissingTags = missingTags.localOnly.length > 0 || missingTags.sedpOnly.length > 0;
+
+ if (itemsWithDifferences.length === 0 && !hasMissingTags) {
+ toast.info(t("excelDownload.noDifferencesToDownload"));
+ return;
+ }
+
+ // Create a new workbook
+ const workbook = new ExcelJS.Workbook();
+ workbook.creator = 'SEDP Compare Tool';
+ workbook.created = new Date();
+
+ // Add a worksheet for attribute differences
+ if (itemsWithDifferences.length > 0) {
+ const worksheet = workbook.addWorksheet(t("excelDownload.attributeDifferencesSheet"));
+
+ // Add headers
+ worksheet.columns = [
+ { header: t("excelDownload.tagNumber"), key: 'tagNo', width: 20 },
+ { header: t("excelDownload.tagDescription"), key: 'tagDesc', width: 30 },
+ { header: t("excelDownload.attribute"), key: 'attribute', width: 25 },
+ { header: t("excelDownload.localValue"), key: 'localValue', width: 20 },
+ { header: t("excelDownload.sedpValue"), 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 === ''
+ ? t("excelDownload.emptyValue")
+ : diff.uom ? `${diff.localValue} ${diff.uom}` : diff.localValue;
+
+ // SEDP value is displayed as-is
+ const sedpDisplay = diff.sedpValue === null || diff.sedpValue === undefined || diff.sedpValue === ''
+ ? t("excelDownload.emptyValue")
+ : 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++;
+ });
+ }
+
+ // Add a worksheet for missing tags if there are any
+ if (hasMissingTags) {
+ const missingWorksheet = workbook.addWorksheet(t("excelDownload.missingTagsSheet"));
+
+ // Add headers
+ missingWorksheet.columns = [
+ { header: t("excelDownload.tagNumber"), key: 'tagNo', width: 20 },
+ { header: t("excelDownload.tagDescription"), key: 'tagDesc', width: 30 },
+ { header: t("excelDownload.status"), key: 'status', width: 20 }
+ ];
+
+ // Style the header row
+ const headerRow = missingWorksheet.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 local-only tags
+ let rowIndex = 2;
+ missingTags.localOnly.forEach(tag => {
+ const row = missingWorksheet.getRow(rowIndex++);
+
+ row.getCell('tagNo').value = tag.tagNo;
+ row.getCell('tagDesc').value = tag.tagDesc;
+ row.getCell('status').value = t("excelDownload.localOnlyStatus");
+
+ // Style the status cell
+ row.getCell('status').font = { color: { argb: 'FFFF8C00' } }; // Orange for local-only
+
+ // Add borders
+ row.eachCell((cell) => {
+ cell.border = {
+ top: { style: 'thin' },
+ left: { style: 'thin' },
+ bottom: { style: 'thin' },
+ right: { style: 'thin' }
+ };
+ });
+ });
+
+ // Add a blank row
+ if (missingTags.localOnly.length > 0 && missingTags.sedpOnly.length > 0) {
+ rowIndex++;
+ }
+
+ // Add SEDP-only tags
+ missingTags.sedpOnly.forEach(tag => {
+ const row = missingWorksheet.getRow(rowIndex++);
+
+ row.getCell('tagNo').value = tag.tagNo;
+ row.getCell('tagDesc').value = tag.tagDesc;
+ row.getCell('status').value = t("excelDownload.sedpOnlyStatus");
+
+ // Style the status cell
+ row.getCell('status').font = { color: { argb: 'FF0000FF' } }; // Blue for SEDP-only
+
+ // Add borders
+ row.eachCell((cell) => {
+ cell.border = {
+ top: { style: 'thin' },
+ left: { style: 'thin' },
+ bottom: { style: 'thin' },
+ right: { style: 'thin' }
+ };
+ });
+ });
+ }
+
+ // 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 = `${t("excelDownload.fileNamePrefix")}_${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(t("excelDownload.downloadComplete"));
+ } catch (error) {
+ console.error("Error exporting to Excel:", error);
+ toast.error(t("excelDownload.downloadFailed"));
+ } finally {
+ setIsExporting(false);
+ }
+ };
+
+ // Determine if there are any differences or missing tags
+ const hasDifferences = comparisonResults.some(item => !item.isMatching);
+ const hasMissingTags = missingTags && (missingTags.localOnly.length > 0 || missingTags.sedpOnly.length > 0);
+ const hasExportableContent = hasDifferences || hasMissingTags;
+
+ return (
+ <Button
+ variant="secondary"
+ onClick={handleExportDifferences}
+ disabled={disabled || isExporting || !hasExportableContent}
+ className="flex items-center gap-2"
+ >
+ {isExporting ? (
+ <Loader className="h-4 w-4 animate-spin" />
+ ) : (
+ <FileDown className="h-4 w-4" />
+ )}
+ {t("excelDownload.downloadButtonText")}
+ </Button>
+ );
+} \ No newline at end of file