This commit is contained in:
rizrmd 2024-06-22 07:56:24 +00:00
parent 7e30a03672
commit cce77e61db
1 changed files with 86 additions and 66 deletions

View File

@ -1,7 +1,7 @@
import { GFCol } from "@/gen/utils"; import { GFCol } from "@/gen/utils";
import { useLocal } from "@/utils/use-local"; import { useLocal } from "@/utils/use-local";
import { ChangeEvent, FC, MouseEvent } from "react"; import { ChangeEvent, FC, MouseEvent } from "react";
import { Workbook } from 'exceljs'; // import { Workbook } from 'exceljs';
// import * as XLSX from "xlsx"; // import * as XLSX from "xlsx";
type ImportExcelProps = { type ImportExcelProps = {
@ -12,7 +12,7 @@ type ImportExcelProps = {
type RowData = { type RowData = {
pk: string | number; pk: string | number;
rows: any; rows: any;
} };
export const ImportExcel: FC<ImportExcelProps> = ({ export const ImportExcel: FC<ImportExcelProps> = ({
gen_fields, gen_fields,
@ -32,7 +32,7 @@ export const ImportExcel: FC<ImportExcelProps> = ({
insertedData: [] as any[], insertedData: [] as any[],
isStopped: false, isStopped: false,
processedRows: 0, processedRows: 0,
firstRow: [] as string[] firstRow: [] as string[],
}); });
const pk = local.pk?.name || "id"; const pk = local.pk?.name || "id";
@ -81,28 +81,30 @@ export const ImportExcel: FC<ImportExcelProps> = ({
reader.onload = async (event: ProgressEvent<FileReader>) => { reader.onload = async (event: ProgressEvent<FileReader>) => {
if (!event.target?.result) return; if (!event.target?.result) return;
const buffer = new Uint8Array(event.target.result as ArrayBuffer); // const buffer = new Uint8Array(event.target.result as ArrayBuffer);
const workbook = new Workbook(); // const workbook = new Workbook();
await workbook.xlsx.load(buffer); // await workbook.xlsx.load(buffer);
const worksheet = workbook.worksheets[0]; // const worksheet = workbook.worksheets[0];
if (worksheet) { // if (worksheet) {
let sheetData = worksheet.getRows(1, worksheet.actualRowCount)?.map(row => row.values); // let sheetData = worksheet
let firstRow = sheetData!.shift(); // .getRows(1, worksheet.actualRowCount)
local.data = sheetData!; // ?.map((row) => row.values);
if (firstRow) { // let firstRow = sheetData!.shift();
local.firstRow = firstRow as string[]; // local.data = sheetData!;
} else { // if (firstRow) {
console.log('firstRow is undefined'); // local.firstRow = firstRow as string[];
} // } else {
local.columns = getAllKeys(local.data); // console.log("firstRow is undefined");
gen_fields.forEach((data: any) => { // }
local.fields.push(JSON.parse(data).name); // local.columns = getAllKeys(local.data);
}); // gen_fields.forEach((data: any) => {
local.tableName = gen_table; // local.fields.push(JSON.parse(data).name);
local.showPreviewExcel = true; // });
local.render(); // local.tableName = gen_table;
} // local.showPreviewExcel = true;
// local.render();
// }
}; };
reader.readAsArrayBuffer(file); reader.readAsArrayBuffer(file);
}; };
@ -124,7 +126,8 @@ export const ImportExcel: FC<ImportExcelProps> = ({
let insertRow: any = {}; let insertRow: any = {};
local.columnMappings.forEach((columnMapping) => { local.columnMappings.forEach((columnMapping) => {
insertRow[pk] = rowIndex; insertRow[pk] = rowIndex;
insertRow[columnMapping.selectedColumn] = row.rows[columnMapping.column]; insertRow[columnMapping.selectedColumn] =
row.rows[columnMapping.column];
}); });
rowIndex++; rowIndex++;
@ -135,13 +138,13 @@ export const ImportExcel: FC<ImportExcelProps> = ({
// }); // });
local.insertedData.push({ local.insertedData.push({
pk: insertRow[pk], pk: insertRow[pk],
rows: insertRow rows: insertRow,
}); });
local.render(); local.render();
local.processedRows++; local.processedRows++;
local.progress = Math.round((local.processedRows / totalRows) * 100); local.progress = Math.round((local.processedRows / totalRows) * 100);
local.render(); local.render();
await new Promise(resolve => setTimeout(resolve, 2000)); await new Promise((resolve) => setTimeout(resolve, 2000));
} }
} }
local.isLoading = false; local.isLoading = false;
@ -201,7 +204,9 @@ export const ImportExcel: FC<ImportExcelProps> = ({
}); });
const table = (db as any)[local.tableName]; const table = (db as any)[local.tableName];
if (table) { if (table) {
let remainingData = local.selectedRows.filter((row) => !ids.includes(row.pk)); let remainingData = local.selectedRows.filter(
(row) => !ids.includes(row.pk)
);
local.showPreviewExcel = false; local.showPreviewExcel = false;
local.isLoading = true; local.isLoading = true;
local.render(); local.render();
@ -209,7 +214,8 @@ export const ImportExcel: FC<ImportExcelProps> = ({
for (const row of remainingData) { for (const row of remainingData) {
let insertRow: any = {}; let insertRow: any = {};
local.columnMappings.forEach((columnMapping) => { local.columnMappings.forEach((columnMapping) => {
insertRow[columnMapping.selectedColumn] = row.rows[columnMapping.column]; insertRow[columnMapping.selectedColumn] =
row.rows[columnMapping.column];
}); });
// let insertedData = await table.create({ data: insertRow }); // let insertedData = await table.create({ data: insertRow });
@ -219,19 +225,19 @@ export const ImportExcel: FC<ImportExcelProps> = ({
// }); // });
local.insertedData.push({ local.insertedData.push({
pk: insertRow[pk], pk: insertRow[pk],
rows: insertRow rows: insertRow,
}); });
local.render(); local.render();
local.processedRows++; local.processedRows++;
local.progress = Math.round((local.processedRows / totalRows) * 100); local.progress = Math.round((local.processedRows / totalRows) * 100);
local.render(); local.render();
await new Promise(resolve => setTimeout(resolve, 2000)); await new Promise((resolve) => setTimeout(resolve, 2000));
} }
local.isLoading = false; local.isLoading = false;
local.isStopped = false; local.isStopped = false;
local.render(); local.render();
} }
} };
const columnMappingChange = const columnMappingChange =
(col: string) => (e: ChangeEvent<HTMLSelectElement>) => { (col: string) => (e: ChangeEvent<HTMLSelectElement>) => {
@ -251,7 +257,7 @@ export const ImportExcel: FC<ImportExcelProps> = ({
return ( return (
<div> <div>
<input type="file" onChange={handleFileUpload} /> <input type="file" onChange={handleFileUpload} />
{local.showPreviewExcel && (local.data.length > 0 && ( {local.showPreviewExcel && local.data.length > 0 && (
<div> <div>
<button <button
onClick={executeImport} onClick={executeImport}
@ -321,7 +327,9 @@ export const ImportExcel: FC<ImportExcelProps> = ({
<input <input
className="c-pointer-events-none" className="c-pointer-events-none"
type="checkbox" type="checkbox"
checked={isRowChecked(row[pk] === undefined ? index : row[pk])} checked={isRowChecked(
row[pk] === undefined ? index : row[pk]
)}
/> />
</div> </div>
</td> </td>
@ -338,25 +346,25 @@ export const ImportExcel: FC<ImportExcelProps> = ({
</tbody> </tbody>
</table> </table>
</div> </div>
))} )}
{local.isLoading && ( {local.isLoading && (
<div style={{ width: '100%', padding: '10px' }}> <div style={{ width: "100%", padding: "10px" }}>
<div <div
style={{ style={{
width: '100%', width: "100%",
backgroundColor: '#f3f3f3', backgroundColor: "#f3f3f3",
borderRadius: '4px', borderRadius: "4px",
overflow: 'hidden' overflow: "hidden",
}} }}
> >
<div <div
style={{ style={{
width: `${local.progress}%`, width: `${local.progress}%`,
height: '24px', height: "24px",
backgroundColor: '#4caf50', backgroundColor: "#4caf50",
textAlign: 'center', textAlign: "center",
lineHeight: '24px', lineHeight: "24px",
color: 'white' color: "white",
}} }}
> >
{local.progress}% {local.progress}%
@ -368,24 +376,26 @@ export const ImportExcel: FC<ImportExcelProps> = ({
<div> <div>
{local.insertedData.length !== local.selectedRows.length && ( {local.insertedData.length !== local.selectedRows.length && (
<div> <div>
{!local.isStopped && (<button {!local.isStopped && (
onClick={handleStopProgress} <button
style={{ onClick={handleStopProgress}
backgroundColor: "red", style={{
border: "none", backgroundColor: "red",
color: "white", border: "none",
padding: "15px 32px", color: "white",
textAlign: "center", padding: "15px 32px",
textDecoration: "none", textAlign: "center",
display: "inline-block", textDecoration: "none",
fontSize: "16px", display: "inline-block",
margin: "4px 2px", fontSize: "16px",
cursor: "pointer", margin: "4px 2px",
borderRadius: "10px", cursor: "pointer",
}} borderRadius: "10px",
> }}
Pause Progress >
</button>)} Pause Progress
</button>
)}
{local.isStopped && ( {local.isStopped && (
<button <button
onClick={continueProgress} onClick={continueProgress}
@ -413,7 +423,10 @@ export const ImportExcel: FC<ImportExcelProps> = ({
<thead> <thead>
<tr> <tr>
{local.columnMappings.map((col) => ( {local.columnMappings.map((col) => (
<th key={col.selectedColumn} style={{ border: "1px solid black", padding: "8px" }}> <th
key={col.selectedColumn}
style={{ border: "1px solid black", padding: "8px" }}
>
{col.selectedColumn} {col.selectedColumn}
</th> </th>
))} ))}
@ -422,8 +435,15 @@ export const ImportExcel: FC<ImportExcelProps> = ({
<tbody> <tbody>
<tr> <tr>
{local.columnMappings.map((col) => ( {local.columnMappings.map((col) => (
<td key={col.selectedColumn} style={{ border: "1px solid black", padding: "8px" }}> <td
{local.insertedData[local.insertedData.length - 1].rows[col.selectedColumn]} key={col.selectedColumn}
style={{ border: "1px solid black", padding: "8px" }}
>
{
local.insertedData[local.insertedData.length - 1].rows[
col.selectedColumn
]
}
</td> </td>
))} ))}
</tr> </tr>