Array of objects to export.
Base filename (without extension); will be sanitized for filesystem safety.
Full filename used for download (including timestamp and extension).
export async function exportToCSV(
data: Record<string, unknown>[],
baseFilename: string,
): Promise<string> {
// Lazy load papaparse only when CSV export is needed
const Papa = await loadPapaparse();
// Convert to CSV using papaparse
const csv = Papa.unparse(data, {
header: true,
quotes: true,
});
// Create blob with UTF-8 BOM prefix for better Excel compatibility
const blob = new Blob([UTF8_BOM, csv], { type: "text/csv;charset=utf-8;" });
const url = URL.createObjectURL(blob);
const link = document.createElement("a");
let appended = false;
try {
// Sanitize and generate timestamped filename
const sanitized = sanitizeFilename(baseFilename);
const timestamp = generateExportTimestamp();
const filename = `${sanitized}-${timestamp}.csv`;
// Trigger download
link.href = url;
link.download = filename;
// Guard against non-DOM contexts where document.body is unavailable
if (!document.body) {
throw new Error(
"Cannot export: document.body is unavailable. " +
"This export utility requires the Electron renderer process with access to DOM APIs. " +
"Ensure this function is called from a React component in the renderer process.",
);
}
document.body.appendChild(link);
appended = true;
link.click();
return filename;
} finally {
// Ensure cleanup always runs
if (appended) {
link.remove();
}
URL.revokeObjectURL(url);
}
}
Exports data to CSV format with UTF-8 BOM for Excel compatibility; triggers browser download.