Merge commit '6447afd1629b6be0ed3ea82d11d8d1641d89e86c' into iipbs/wr/excel
This commit is contained in:
@@ -43,6 +43,7 @@
|
||||
"sonner": "^2.0.1",
|
||||
"tailwind-merge": "^3.0.1",
|
||||
"xlsx": "^0.18.5",
|
||||
"xlsx-populate": "^1.21.0",
|
||||
"zod": "^3.24.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -58,6 +59,7 @@
|
||||
"@storybook/test": "^8.5.3",
|
||||
"@storybook/theming": "^8.5.5",
|
||||
"@vitejs/plugin-react": "^4.3.4",
|
||||
"@xlsx/xlsx-populate": "^0.0.8",
|
||||
"autoprefixer": "^10.4.20",
|
||||
"eslint": "^9.17.0",
|
||||
"eslint-plugin-react-hooks": "^5.0.0",
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
import * as XlsxPopulate from '@xlsx/xlsx-populate';
|
||||
export const excelStyle = async (data: ArrayBuffer, range: string = "A1:V3", fileNm:string) => {
|
||||
console.log("excelStyle", data, range, fileNm);
|
||||
const workbook = await XlsxPopulate.Workbook.fromData(data);
|
||||
const rangeCells = workbook.activeSheet(0)?.sheet(0)?.range(range);
|
||||
console.log(rangeCells);
|
||||
rangeCells?.style((styleQ)=>{
|
||||
console.log(styleQ);
|
||||
styleQ.fill({ type: "solid", color: {rgb:"9bc1e7"} });
|
||||
styleQ.borderEach( { style: "thin", color: { rgb: "FFFFFF" } } );
|
||||
styleQ.wrapText(true);
|
||||
// styleQ.fontColor({rgb:"FFFFFF"});
|
||||
styleQ.fontSize(15);
|
||||
styleQ.horizontalAlignment("center");
|
||||
styleQ.verticalAlignment("center");
|
||||
styleQ.bold(true);
|
||||
});
|
||||
const outputData = await workbook.output("array-buffer");
|
||||
const blob = new Blob([outputData], { type: "application/octet-stream" });
|
||||
const link = document.createElement("a");
|
||||
link.href = URL.createObjectURL(blob);
|
||||
link.download = fileNm+".xlsx";
|
||||
link.click();
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
import * as XLSX from 'xlsx';
|
||||
import { excelStyle } from './excelStyle';
|
||||
|
||||
type ExcelDownloadProps = {
|
||||
data: JSON | JSON[];
|
||||
fileName: string;
|
||||
sheetNameArray: string[];
|
||||
}
|
||||
|
||||
export const downloadExcel = ({ data, fileName = new Date().getTime().toString() + '.xlsx', sheetNameArray = ["Sheet1"] }: ExcelDownloadProps) => {
|
||||
const worksheet = XLSX.utils.json_to_sheet(Array.isArray(data) ? data : [data]);
|
||||
const workbook = XLSX.utils.book_new();
|
||||
XLSX.utils.book_append_sheet(workbook, worksheet, sheetNameArray[0]);
|
||||
//let buffer = XLSX.write(workbook, { bookType: "xlsx", type: "buffer" });
|
||||
//XLSX.write(workbook, { bookType: "xlsx", type: "binary" });
|
||||
XLSX.writeFile(workbook, fileName + '.xlsx');
|
||||
};
|
||||
|
||||
|
||||
|
||||
export const filePicked=(oFile: File, headerNum:number=0):Promise<JSON | undefined> =>{
|
||||
// Create A File Reader HTML5
|
||||
const reader = new FileReader();
|
||||
return new Promise<JSON | undefined>((resolve, reject) => {
|
||||
// Ready The Event For When A File Gets Selected
|
||||
reader.onload = function (e) {
|
||||
const data = e.target?.result;
|
||||
if (!data) {
|
||||
console.error("Failed to read file: e.target.result is null");
|
||||
resolve(undefined);
|
||||
return;
|
||||
}
|
||||
const wb = XLSX.read(data, { type: 'binary' });
|
||||
let jsonXls: JSON | undefined;
|
||||
|
||||
//TODO 시트가 2개이상일 경우 마지막 시트의 데이터만 표출됨
|
||||
// Loop Over Each Sheet
|
||||
wb.SheetNames.forEach(function (sheetName) {
|
||||
// Obtain The Current Row As CSV
|
||||
const sheet = wb.Sheets[sheetName];
|
||||
|
||||
if (sheet) {
|
||||
jsonXls = XLSX.utils.sheet_to_json(sheet, { range: headerNum }) as unknown as JSON;
|
||||
} else {
|
||||
console.error(`Sheet "${sheetName}" is undefined.`);
|
||||
}
|
||||
});
|
||||
resolve(jsonXls);
|
||||
};
|
||||
|
||||
reader.onerror = function () {
|
||||
console.error("Error reading file");
|
||||
reject(undefined);
|
||||
};
|
||||
|
||||
// Tell JS To Start Reading The File.. You could delay this if desired
|
||||
reader.readAsBinaryString(oFile);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
export const filePickedBlob=(oFile: ArrayBuffer, data:[][],fileNm:string, headerNum:number=0, headerRange='A1:V3'):Promise<JSON | undefined> =>{ // Create A File Reader HTML5
|
||||
return new Promise<JSON | undefined>(() => {
|
||||
// Ready The Event For When A File Gets Selected
|
||||
const wb = XLSX.read(oFile, { type: 'binary' });
|
||||
// Loop Over Each Sheet
|
||||
wb.SheetNames.forEach(async function (sheetName, index) {
|
||||
// Obtain The Current Row As CSV
|
||||
if(index==0){
|
||||
const sheet = wb.Sheets[sheetName];
|
||||
if (sheet) {
|
||||
//오리진 확인 test 필요
|
||||
// const sheet = XLSX.utils.json_to_sheet(data);
|
||||
XLSX.utils.sheet_add_aoa(sheet, data, { origin: 'A'+headerNum });
|
||||
// XLSX.utils.book_append_sheet(wb, sheet, 'test');
|
||||
await excelStyle(XLSX.write(wb, { bookType: "xlsx", type: "buffer" }), headerRange, fileNm)
|
||||
} else {
|
||||
console.error(`Sheet "${sheetName}" is undefined.`);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
export * from "./chart";
|
||||
export * from "./date_picker";
|
||||
export * from "./dialog_ui";
|
||||
export * from "./excel_download";
|
||||
export * from "./excel";
|
||||
export * from "./file-upload";
|
||||
export * from "./form";
|
||||
export * from "./form_ui";
|
||||
@@ -19,3 +19,4 @@ export * from "./tab";
|
||||
export * from "./table";
|
||||
export * from "./table_div";
|
||||
export * from "./title";
|
||||
|
||||
|
||||
Reference in New Issue
Block a user