185 lines
4.6 KiB
TypeScript
185 lines
4.6 KiB
TypeScript
// Export utilities for CSV and PDF
|
|
|
|
export interface ExportData {
|
|
headers: string[];
|
|
rows: (string | number)[][];
|
|
title?: string;
|
|
}
|
|
|
|
/**
|
|
* Export data to CSV
|
|
*/
|
|
export function exportToCSV(data: ExportData, filename: string = 'export.csv'): void {
|
|
const { headers, rows } = data;
|
|
|
|
// Create CSV content
|
|
const csvContent = [
|
|
headers.join(','),
|
|
...rows.map((row) => row.map((cell) => `"${cell}"`).join(',')),
|
|
].join('\n');
|
|
|
|
// Create blob and download
|
|
const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });
|
|
const link = document.createElement('a');
|
|
const url = URL.createObjectURL(blob);
|
|
|
|
link.setAttribute('href', url);
|
|
link.setAttribute('download', filename);
|
|
link.style.visibility = 'hidden';
|
|
document.body.appendChild(link);
|
|
link.click();
|
|
document.body.removeChild(link);
|
|
URL.revokeObjectURL(url);
|
|
}
|
|
|
|
/**
|
|
* Export table data to CSV
|
|
*/
|
|
export function exportTableToCSV(
|
|
tableId: string,
|
|
filename: string = 'table-export.csv'
|
|
): void {
|
|
const table = document.getElementById(tableId) as HTMLTableElement;
|
|
if (!table) {
|
|
console.error('Table not found:', tableId);
|
|
return;
|
|
}
|
|
|
|
const headers: string[] = [];
|
|
const rows: (string | number)[][] = [];
|
|
|
|
// Get headers
|
|
const headerRow = table.querySelector('thead tr');
|
|
if (headerRow) {
|
|
headerRow.querySelectorAll('th').forEach((th) => {
|
|
headers.push(th.textContent?.trim() || '');
|
|
});
|
|
}
|
|
|
|
// Get rows
|
|
table.querySelectorAll('tbody tr').forEach((tr) => {
|
|
const row: (string | number)[] = [];
|
|
tr.querySelectorAll('td').forEach((td) => {
|
|
row.push(td.textContent?.trim() || '');
|
|
});
|
|
if (row.length > 0) {
|
|
rows.push(row);
|
|
}
|
|
});
|
|
|
|
exportToCSV({ headers, rows }, filename);
|
|
}
|
|
|
|
/**
|
|
* Export data to JSON
|
|
*/
|
|
export function exportToJSON(data: any, filename: string = 'export.json'): 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.setAttribute('href', url);
|
|
link.setAttribute('download', filename);
|
|
link.style.visibility = 'hidden';
|
|
document.body.appendChild(link);
|
|
link.click();
|
|
document.body.removeChild(link);
|
|
URL.revokeObjectURL(url);
|
|
}
|
|
|
|
/**
|
|
* Generate PDF using browser print (simple approach)
|
|
* For more advanced PDF generation, consider using libraries like jsPDF or pdfmake
|
|
*/
|
|
export function exportToPDF(
|
|
elementId: string,
|
|
filename: string = 'export.pdf',
|
|
title?: string
|
|
): void {
|
|
const element = document.getElementById(elementId);
|
|
if (!element) {
|
|
console.error('Element not found:', elementId);
|
|
return;
|
|
}
|
|
|
|
// Create a new window for printing
|
|
const printWindow = window.open('', '_blank');
|
|
if (!printWindow) {
|
|
console.error('Could not open print window');
|
|
return;
|
|
}
|
|
|
|
printWindow.document.write(`
|
|
<html>
|
|
<head>
|
|
<title>${title || 'Export'}</title>
|
|
<style>
|
|
body {
|
|
font-family: Arial, sans-serif;
|
|
margin: 20px;
|
|
}
|
|
table {
|
|
width: 100%;
|
|
border-collapse: collapse;
|
|
margin: 20px 0;
|
|
}
|
|
th, td {
|
|
border: 1px solid #ddd;
|
|
padding: 8px;
|
|
text-align: left;
|
|
}
|
|
th {
|
|
background-color: #f2f2f2;
|
|
font-weight: bold;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
${element.innerHTML}
|
|
</body>
|
|
</html>
|
|
`);
|
|
|
|
printWindow.document.close();
|
|
printWindow.focus();
|
|
|
|
// Wait for content to load, then print
|
|
setTimeout(() => {
|
|
printWindow.print();
|
|
// Optionally close after printing
|
|
// printWindow.close();
|
|
}, 250);
|
|
}
|
|
|
|
/**
|
|
* Format data for export from DataTable component
|
|
*/
|
|
export function formatDataForExport<T extends Record<string, any>>(
|
|
data: T[],
|
|
columns: Array<{ key: string; header: string; render?: (row: T) => any }>
|
|
): ExportData {
|
|
const headers = columns.map((col) => col.header);
|
|
const rows = data.map((row) =>
|
|
columns.map((col) => {
|
|
if (col.render) {
|
|
// For rendered cells, try to extract meaningful text
|
|
const rendered = col.render(row);
|
|
if (typeof rendered === 'string' || typeof rendered === 'number') {
|
|
return rendered;
|
|
}
|
|
// For React elements, fall back to raw value
|
|
return String(row[col.key] || '');
|
|
}
|
|
const value = row[col.key];
|
|
if (value === null || value === undefined) {
|
|
return '';
|
|
}
|
|
return String(value);
|
|
})
|
|
);
|
|
|
|
return { headers, rows };
|
|
}
|
|
|