Files
drawNET_test/static/js/modules/graph/io/excel_exporter.js
T
2026-04-22 21:11:57 +09:00

121 lines
3.9 KiB
JavaScript

import { state } from '../../state.js';
import { logger } from '../../utils/logger.js';
import { t } from '../../i18n.js';
/**
* excel_exporter.js - Exports topology data to a structured CSV format compatible with Excel.
* Includes all metadata (Parent Group, Tags, Description) for both Nodes and Edges.
*/
export function exportToExcel() {
if (!state.graph) return;
const nodes = state.graph.getNodes();
const edges = state.graph.getEdges();
if (nodes.length === 0 && edges.length === 0) {
alert(t('pptx_no_data') || 'No data to export.');
return;
}
// Header Definition (Unified for mapping ease)
const headers = [
"Category",
"ID",
"Label/Name",
"Type",
"Parent Group",
"Source (ID/Label)",
"Target (ID/Label)",
"Tags",
"Description",
"IP Address",
"Vendor",
"Model",
"Asset Tag"
];
const csvRows = [];
// Add Nodes
nodes.forEach(node => {
const d = node.getData() || {};
const label = node.attr('label/text') || d.label || '';
// Find Parent Group Name
let parentName = '';
const parent = node.getParent();
if (parent && parent.isNode()) {
parentName = parent.attr('label/text') || parent.getData()?.label || parent.id;
}
csvRows.push([
"Node",
node.id,
label,
d.type || '',
parentName,
"", // Source
"", // Target
(d.tags || []).join('; '),
d.description || '',
d.ip || '',
d.vendor || '',
d.model || '',
d.asset_tag || ''
]);
});
// Add Edges
edges.forEach(edge => {
const d = edge.getData() || {};
const label = (edge.getLabels()[0]?.attrs?.label?.text) || d.label || '';
const sourceCell = edge.getSourceCell();
const targetCell = edge.getTargetCell();
const sourceStr = sourceCell ? (sourceCell.attr('label/text') || sourceCell.id) : (edge.getSource().id || 'Unknown');
const targetStr = targetCell ? (targetCell.attr('label/text') || targetCell.id) : (edge.getTarget().id || 'Unknown');
csvRows.push([
"Edge",
edge.id,
label,
d.type || 'Connection',
"", // Parent Group (Edges usually not grouped in same way)
sourceStr,
targetStr,
(d.tags || []).join('; '),
d.description || '',
"", // IP
"", // Vendor
"", // Model
d.asset_tag || ''
]);
});
import('../../ui/toast.js').then(m => m.showToast(t('msg_export_start').replace('{format}', 'Excel'), 'info', 2000));
// Generate CSV Content with UTF-8 BOM
const csvContent = "\uFEFF" + // UTF-8 BOM for Excel (Required for Korean/Special chars)
headers.join(',') + "\n" +
csvRows.map(row => row.map(cell => `"${String(cell).replace(/"/g, '""')}"`).join(',')).join('\n');
// Trigger Download
const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });
const url = URL.createObjectURL(blob);
const link = document.createElement("a");
const timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, 19);
const projectName = document.getElementById('project-title')?.innerText || "Project";
link.setAttribute("href", url);
link.setAttribute("download", `drawNET_Inventory_${projectName}_${timestamp}.csv`);
link.style.visibility = 'hidden';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
import('../../ui/toast.js').then(m => m.showToast(t('msg_export_success').replace('{format}', 'Excel'), 'success'));
logger.high(`Inventory exported for ${nodes.length} nodes and ${edges.length} edges.`);
}