import { GFCol } from "@/gen/utils"; import { useLocal } from "@/utils/use-local"; import { ChangeEvent, FC, MouseEvent } from "react"; // import { Workbook } from 'exceljs'; // import * as XLSX from "xlsx"; type ImportExcelProps = { gen_fields: string[]; gen_table: string; }; type RowData = { pk: string | number; rows: any; }; export const ImportExcel: FC = ({ gen_fields, gen_table, }) => { const local = useLocal({ data: [] as any[], columns: [] as string[], fields: [] as string[], tableName: "", selectedRows: [] as RowData[], pk: null as null | GFCol, columnMappings: [] as { column: string; selectedColumn: string }[], isLoading: false, progress: 0, showPreviewExcel: false, insertedData: [] as any[], isStopped: false, processedRows: 0, firstRow: [] as string[], }); const pk = local.pk?.name || "id"; const getAllKeys = (arr: Array>): string[] => { const keysSet = new Set(); arr.forEach((obj) => { Object.keys(obj).forEach((key) => keysSet.add(key)); }); return Array.from(keysSet); }; // const handleFileUpload = (e: ChangeEvent) => { // const file = e.target.files?.[0]; // if (!file) return; // const reader = new FileReader(); // reader.onload = (event: ProgressEvent) => { // if (!event.target?.result) return; // const workbook = XLSX.read(event.target.result, { type: "binary" }); // const sheetName = workbook.SheetNames[0]; // const sheet = workbook.Sheets[sheetName]; // const sheetData = XLSX.utils.sheet_to_json(sheet); // local.data = sheetData; // local.columns = getAllKeys(local.data); // gen_fields.forEach((data: any) => { // local.fields.push(JSON.parse(data).name); // }); // local.tableName = gen_table; // local.showPreviewExcel = true; // local.render(); // }; // reader.readAsBinaryString(file); // }; const handleFileUpload = async (e: ChangeEvent) => { const file = e.target.files?.[0]; if (!file) return; const reader = new FileReader(); reader.onload = async (event: ProgressEvent) => { if (!event.target?.result) return; // const buffer = new Uint8Array(event.target.result as ArrayBuffer); // const workbook = new Workbook(); // await workbook.xlsx.load(buffer); // const worksheet = workbook.worksheets[0]; // if (worksheet) { // let sheetData = worksheet // .getRows(1, worksheet.actualRowCount) // ?.map((row) => row.values); // let firstRow = sheetData!.shift(); // local.data = sheetData!; // if (firstRow) { // local.firstRow = firstRow as string[]; // } else { // console.log("firstRow is undefined"); // } // local.columns = getAllKeys(local.data); // gen_fields.forEach((data: any) => { // local.fields.push(JSON.parse(data).name); // }); // local.tableName = gen_table; // local.showPreviewExcel = true; // local.render(); // } }; reader.readAsArrayBuffer(file); }; const executeImport = async (e: MouseEvent) => { e.preventDefault(); const table = (db as any)[local.tableName]; if (table) { local.showPreviewExcel = false; local.isLoading = true; local.progress = 0; local.insertedData = []; local.render(); const totalRows = local.selectedRows.length; local.processedRows = 0; let rowIndex = 0; for (const row of local.selectedRows) { if (!local.isStopped) { let insertRow: any = {}; local.columnMappings.forEach((columnMapping) => { insertRow[pk] = rowIndex; insertRow[columnMapping.selectedColumn] = row.rows[columnMapping.column]; }); rowIndex++; local.insertedData.push({ pk: insertRow[pk], rows: insertRow, }); local.render(); local.processedRows++; local.progress = Math.round((local.processedRows / totalRows) * 100); local.render(); await new Promise((resolve) => setTimeout(resolve, 2000)); } } local.isLoading = false; local.render(); } }; const headerCheckboxClick = (e: ChangeEvent) => { if (e.target.checked) { local.data.forEach((data, key) => { local.selectedRows.push({ pk: data[pk] === undefined ? key : data[pk], rows: data, }); }); local.render(); console.log("Select All", local.selectedRows); } else { local.selectedRows = []; local.render(); console.log("Deselect all", local.selectedRows); } }; const checkboxClick = (rowId: any) => (e: MouseEvent) => { e.preventDefault(); e.stopPropagation(); const checked = !!local.selectedRows.find((data) => data.pk === rowId); if (!checked) { const checkedRowData = local.data.filter((row) => row[pk] === rowId); local.selectedRows.push({ pk: rowId, rows: checkedRowData, }); local.render(); console.log("selected", local.selectedRows); } else { local.selectedRows = local.selectedRows.filter( (data) => data.pk !== rowId ); local.render(); console.log("deselected", local.selectedRows); } }; const handleStopProgress = (e: MouseEvent) => { e.preventDefault(); local.isStopped = true; local.render(); }; const continueProgress = async (e: MouseEvent) => { e.preventDefault(); let ids = [] as any[]; local.insertedData.forEach((row) => { ids.push(row.pk); }); const table = (db as any)[local.tableName]; if (table) { let remainingData = local.selectedRows.filter( (row) => !ids.includes(row.pk) ); local.showPreviewExcel = false; local.isLoading = true; local.render(); const totalRows = local.selectedRows.length; for (const row of remainingData) { let insertRow: any = {}; local.columnMappings.forEach((columnMapping) => { insertRow[columnMapping.selectedColumn] = row.rows[columnMapping.column]; }); // let insertedData = await table.create({ data: insertRow }); // local.insertedData.push({ // pk: insertedData.id, // rows: insertedData // }); local.insertedData.push({ pk: insertRow[pk], rows: insertRow, }); local.render(); local.processedRows++; local.progress = Math.round((local.processedRows / totalRows) * 100); local.render(); await new Promise((resolve) => setTimeout(resolve, 2000)); } local.isLoading = false; local.isStopped = false; local.render(); } }; const columnMappingChange = (col: string) => (e: ChangeEvent) => { const selectedValue = e.target.value; local.columnMappings.push({ column: col, selectedColumn: selectedValue, }); local.render(); console.log("column mappings", local.columnMappings); }; const isRowChecked = (id: any) => { return local.selectedRows.some((checked) => checked.pk === id); }; return (
{local.showPreviewExcel && local.data.length > 0 && (

Your Excel Data:

{local.columns.map((col: any) => ( ))} {local.data.map((row, index) => ( {local.columns.map((col) => ( ))} ))}
{local.firstRow[col]}{" "}
{row[col]}
)} {local.isLoading && (
{local.progress}%
)} {local.insertedData.length > 0 && (
{local.insertedData.length !== local.selectedRows.length && (
{!local.isStopped && ( )} {local.isStopped && ( )}
)}

Inserted Data:

{local.columnMappings.map((col) => ( ))} {local.columnMappings.map((col) => ( ))}
{col.selectedColumn}
{ local.insertedData[local.insertedData.length - 1].rows[ col.selectedColumn ] }
)}
); };