import { useCallback, useState } from 'react'; import { useDataContext } from './DataTable'; const headerStyle = { fill: { patternType: 'solid', fgColor: { rgb: "FBF6D900" } }, font: { bold: true } }; const extraStyle = { fill: { patternType: 'solid', fgColor: { rgb: "E5E4E200" } }, alignment: { horizontal: 'right' }, font: { bold: true } }; export default function useExporter(header: any[], params: any, map: Function, extra: any = null, transform: Function | null = null): any { const [loading, setLoading] = useState(false); const fetchData = useDataContext(); const handleExport = useCallback(async function (name) { const _XLSX = await import('sheetjs-style-v2'); const XLSX = _XLSX?.default || _XLSX; setLoading(true); try { const data = await fetchData({itemPerPage: -1, ...(params || {})}); const array = (extra && extra.length > 0 ? extra.concat([[]]) : []) .concat([header]) .concat((transform ? transform(data.data) : data.data).map(map)); const headerStart = (((extra && extra.length && (extra.length + 1)) || 0) + 1).toString(); const ws = XLSX.utils.aoa_to_sheet(array); for (let i = 0; i < (((extra && extra.length && (extra.length)) || 0)); ++i) { ws["A" + (i+1).toString()].s = extraStyle; } ws['!cols'] = formatExcelCols([header].concat(data.data.map(map))); for (let i = 0; i < header.length; ++i) { ws[String.fromCharCode(65 + i) + headerStart].s = headerStyle; } ws['!autofilter'] = { ref: "A" + headerStart + ":" + String.fromCharCode(65 + header.length - 1) + array.length }; const new_workbook = XLSX.utils.book_new(); const finalName = name || 'Report'; XLSX.utils.book_append_sheet(new_workbook, ws, finalName.length > 30 ? 'Report' : finalName); XLSX.writeFile(new_workbook, (name || 'Report') + '.xlsx'); } finally { setLoading(false); } }, [fetchData, header, map, params, setLoading]); return [ handleExport, loading ]; } function formatExcelCols(json: any[]) { let widthArr = json[0].map(key => { return {width: (key || '').toString().length + 2} // plus 2 to account for short object keys }); for (let i = 0; i < json.length; i++) { let value = json[i]; for (let j = 0; j < value.length; j++) { if (value[j]?.length > widthArr[j].width) { widthArr[j].width = value[j].length; } } } return widthArr; }