File size: 4,466 Bytes
d97b8f9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
import * as XLSX from 'xlsx';
import { toast } from './custom-toast';

interface ExportOptions {
  filename: string;
  sheetName?: string;
  headerStyle?: any;
  cellStyles?: { [key: string]: any };
  columnWidths?: { [key: string]: number };
}

/**

 * Export data to Excel with advanced formatting options

 * @param data The data to export

 * @param options Export options including filename and formatting

 */
export const exportToExcel = (data: any[], options: ExportOptions) => {
  console.log("exportToExcel function called with", { 
    dataLength: data?.length,
    options 
  });

  if (!data || data.length === 0) {
    console.error("No data to export");
    toast.error("No data to export");
    return;
  }

  try {
    // Set default options
    const sheetName = options.sheetName || "Report";
    console.log(`Creating worksheet with sheetName: ${sheetName}`);
    
    // Create a worksheet
    const worksheet = XLSX.utils.json_to_sheet(data);
    console.log("Worksheet created successfully");
    
    // Apply column widths if provided
    if (options.columnWidths) {
      console.log("Applying column widths");
      worksheet['!cols'] = Object.entries(options.columnWidths).map(([key, width]) => ({
        wch: width
      }));
    }
    
    // Create a workbook
    const workbook = XLSX.utils.book_new();
    XLSX.utils.book_append_sheet(workbook, worksheet, sheetName);
    console.log("Workbook created and worksheet appended");
    
    // Generate Excel file
    console.log(`Writing Excel file with filename: ${options.filename}.xlsx`);
    XLSX.writeFile(workbook, `${options.filename}.xlsx`);
    console.log("Excel file written successfully");
    
    toast.success(`${options.filename} exported successfully`);
    return true;
  } catch (error) {
    console.error('Excel export error:', error);
    toast.error("Failed to export data");
    return false;
  }
};

/**

 * Export multiple datasets to Excel with each dataset in a separate sheet

 * @param datasets Object containing multiple datasets, with keys as sheet names

 * @param filename Filename for the exported Excel file

 */
export const exportMultipleSheets = (datasets: { [key: string]: any[] }, filename: string) => {
  if (!datasets || Object.keys(datasets).length === 0) {
    toast.error("No data to export");
    return;
  }

  try {
    // Create a workbook
    const workbook = XLSX.utils.book_new();
    
    // Add each dataset as a separate sheet
    Object.entries(datasets).forEach(([sheetName, data]) => {
      if (data && data.length > 0) {
        const worksheet = XLSX.utils.json_to_sheet(data);
        XLSX.utils.book_append_sheet(workbook, worksheet, sheetName);
      }
    });
    
    // Generate Excel file
    XLSX.writeFile(workbook, `${filename}.xlsx`);
    
    toast.success(`${filename} exported successfully`);
    return true;
  } catch (error) {
    console.error('Multi-sheet Excel export error:', error);
    toast.error("Failed to export data");
    return false;
  }
};

/**

 * Format data for Excel export 

 * @param data Raw data that might need formatting

 * @param formatOptions Formatting options for specific fields

 */
export const formatDataForExport = (data: any[], formatOptions: { [key: string]: (value: any) => any } = {}) => {
  return data.map(item => {
    const formattedItem = { ...item };
    
    Object.entries(formatOptions).forEach(([key, formatter]) => {
      if (item[key] !== undefined) {
        formattedItem[key] = formatter(item[key]);
      }
    });
    
    return formattedItem;
  });
};

/**

 * Convert chart data to a simplified format for Excel export

 * @param chartData Data used for charts (may contain complex objects)

 */
export const prepareChartDataForExport = (chartData: any[]) => {
  // Filter out non-serializable properties and format data
  return chartData.map(item => {
    const exportableItem: any = {};
    
    Object.entries(item).forEach(([key, value]) => {
      // Skip complex objects like React refs, DOM elements, or functions
      if (
        typeof value !== 'function' &&
        !(value instanceof Element) &&
        !key.startsWith('_') &&
        key !== 'color' // Skip color property which is used only for UI
      ) {
        exportableItem[key] = value;
      }
    });
    
    return exportableItem;
  });
};