/** * Utility functions for data export */ type CsvRow = (string | number | boolean | null | undefined)[]; /** * Export data to CSV file */ export const exportToCSV = ( data: CsvRow[], filename: string, options?: { separator?: string; includeDate?: boolean } ): void => { const { separator = ',', includeDate = true } = options || {}; const csvContent = data .map((row) => row .map((cell) => { if (cell === null || cell === undefined) return ''; const cellStr = String(cell); // Escape quotes and wrap in quotes if contains separator or quotes if (cellStr.includes(separator) || cellStr.includes('"') || cellStr.includes('\n')) { return `"${cellStr.replace(/"/g, '""')}"`; } return cellStr; }) .join(separator) ) .join('\n'); const blob = new Blob(['\ufeff' + csvContent], { type: 'text/csv;charset=utf-8;' }); const link = document.createElement('a'); const url = URL.createObjectURL(blob); const date = includeDate ? `-${new Date().toISOString().split('T')[0]}` : ''; link.href = url; link.download = `${filename}${date}.csv`; link.style.display = 'none'; document.body.appendChild(link); link.click(); document.body.removeChild(link); URL.revokeObjectURL(url); }; /** * Export data to JSON file */ export const exportToJSON = (data: T, filename: string): void => { const jsonContent = JSON.stringify(data, null, 2); const blob = new Blob([jsonContent], { type: 'application/json;charset=utf-8;' }); const link = document.createElement('a'); const url = URL.createObjectURL(blob); link.href = url; link.download = `${filename}-${new Date().toISOString().split('T')[0]}.json`; link.style.display = 'none'; document.body.appendChild(link); link.click(); document.body.removeChild(link); URL.revokeObjectURL(url); }; /** * Format date for export */ export const formatDateForExport = (date: string | Date | null | undefined): string => { if (!date) return ''; const d = new Date(date); return d.toLocaleDateString('fr-FR', { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', }); };