-
+ return toast.custom((t) => (
+
+
+
- ))
- )
-}
\ No newline at end of file
+
+
+ {url && buttonName ? (
+
+ ) : (
+ <>>
+ )}
+
+
+
+
+
+ ));
+}
diff --git a/apps/wr/public/sample.xlsx b/apps/wr/public/sample.xlsx
new file mode 100644
index 000000000..ee4b23edb
Binary files /dev/null and b/apps/wr/public/sample.xlsx differ
diff --git a/apps/wr/public/sample_rainSttn.xlsx b/apps/wr/public/sample_rainSttn.xlsx
new file mode 100644
index 000000000..006e06aba
Binary files /dev/null and b/apps/wr/public/sample_rainSttn.xlsx differ
diff --git a/apps/wr/public/sample_rainSttn_test.xlsx b/apps/wr/public/sample_rainSttn_test.xlsx
new file mode 100644
index 000000000..57ea2f222
Binary files /dev/null and b/apps/wr/public/sample_rainSttn_test.xlsx differ
diff --git a/apps/wr/public/sample_rainy.xlsx b/apps/wr/public/sample_rainy.xlsx
new file mode 100644
index 000000000..ee4b23edb
Binary files /dev/null and b/apps/wr/public/sample_rainy.xlsx differ
diff --git a/apps/wr/tailwind.config.ts b/apps/wr/tailwind.config.ts
index dc688050e..00237ea18 100644
--- a/apps/wr/tailwind.config.ts
+++ b/apps/wr/tailwind.config.ts
@@ -5,7 +5,7 @@ import presetConfig from "../../tailwind.config.preset";
export default {
presets: [presetConfig],
content: [
- "./src/**/*.{js,ts,jsx,tsx,mdx}",
+ "./app/**/*.{js,ts,jsx,tsx,mdx}",
"./components/**/*.{js,ts,jsx,tsx,mdx}",
"../../packages/common/components/src/ui/**/*.{js,ts,jsx,tsx,mdx}",
"../../packages/common/business_components/src/ui/**/*.{js,ts,jsx,tsx,mdx}",
diff --git a/packages/common/business_components/package.json b/packages/common/business_components/package.json
index 1f02a708e..a23f31058 100644
--- a/packages/common/business_components/package.json
+++ b/packages/common/business_components/package.json
@@ -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",
diff --git a/packages/common/business_components/src/ui/excel/excelStyle.tsx b/packages/common/business_components/src/ui/excel/excelStyle.tsx
new file mode 100644
index 000000000..2475d1453
--- /dev/null
+++ b/packages/common/business_components/src/ui/excel/excelStyle.tsx
@@ -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();
+}
\ No newline at end of file
diff --git a/packages/common/business_components/src/ui/excel/index.tsx b/packages/common/business_components/src/ui/excel/index.tsx
new file mode 100644
index 000000000..c17aa0660
--- /dev/null
+++ b/packages/common/business_components/src/ui/excel/index.tsx
@@ -0,0 +1,86 @@
+import * as XLSX from 'xlsx';
+import { excelStyle } from './excelStyle';
+
+type ExcelDownloadProps = {
+ data: JSON | JSON[];
+ fileName: string;
+ sheetNameArray: string[];
+ headerRange: string;
+}
+
+export const downloadExcel = ({ data, fileName = new Date().getTime().toString() + '.xlsx', sheetNameArray = ["Sheet1"], headerRange='A1:V3'}: 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]);
+ excelStyle(XLSX.write(workbook, { bookType: "xlsx", type: "buffer" }), headerRange, fileName);
+};
+
+
+
+export const filePicked=(oFile: File, headerNum:number=0):Promise
=>{
+ // Create A File Reader HTML5
+ const reader = new FileReader();
+ return new Promise((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;
+ }
+ //셀데이터에서 데이트 형식으로 입력하면 yyyymmdd 형식으로 변환
+ const wb = XLSX.read(data, { type: 'binary', cellDates: true, dateNF: "yyyymmdd" });
+ let jsonXls: JSON | undefined;
+
+ // Loop Over Each Sheet
+ wb.SheetNames.forEach(function (sheetName,index ) {
+ // Obtain The Current Row As CSV
+ // 일단 첫번째 시트만 읽을 수 있도록 수정
+ if(index ===0){
+ const sheet = wb.Sheets[sheetName];
+
+ if (sheet) {
+ jsonXls = XLSX.utils.sheet_to_json(sheet, { range: headerNum, raw:false }) 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 =>{ // Create A File Reader HTML5
+ return new Promise(() => {
+ // 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.`);
+ }
+ }
+ });
+ });
+ }
\ No newline at end of file
diff --git a/packages/common/business_components/src/ui/excel_download/index.tsx b/packages/common/business_components/src/ui/excel_download/index.tsx
deleted file mode 100644
index 21d009dbc..000000000
--- a/packages/common/business_components/src/ui/excel_download/index.tsx
+++ /dev/null
@@ -1,52 +0,0 @@
-import * as XLSX from 'xlsx';
-
-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 =>{
- // Create A File Reader HTML5
- const reader = new FileReader();
- return new Promise((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;
- // 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);
- });
-}
\ No newline at end of file
diff --git a/packages/common/business_components/src/ui/file-upload/index.tsx b/packages/common/business_components/src/ui/file-upload/index.tsx
index 3d581ed05..4c6dcec00 100644
--- a/packages/common/business_components/src/ui/file-upload/index.tsx
+++ b/packages/common/business_components/src/ui/file-upload/index.tsx
@@ -6,14 +6,22 @@ const dropZoneConfig = {
maxSize: 1024 * 1024 * 4,
multiple: true,
};
+
+
+ interface FileUploadProps {
+ files: File[]; // 파일 배열
+ setFiles: (files: File[] | null) => void; // 파일 배열 세터
+ fileTypes?: string; // 옵션 (파일 확장자 문자열)
+ }
+
export const FileUpload =
-(({ ...props }) => {
+({ files, setFiles, fileTypes }: FileUploadProps) => {
return (
- Click to upload
- or drag and drop
+ 클릭 후 업로드
+ 혹은 파일을 드래그 해주세요
- {!props?.fileTypes?"SVG, PNG, JPG, GIF":props?.fileTypes}
+ {!fileTypes?"SVG, PNG, JPG, GIF":fileTypes}
)
-})
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/packages/common/business_components/src/ui/index.ts b/packages/common/business_components/src/ui/index.ts
index e591be5b5..90bf029c0 100644
--- a/packages/common/business_components/src/ui/index.ts
+++ b/packages/common/business_components/src/ui/index.ts
@@ -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";
+
diff --git a/packages/common/business_components/src/ui/search_base_form/index.tsx b/packages/common/business_components/src/ui/search_base_form/index.tsx
index 90ad0b05e..9dc1bf735 100644
--- a/packages/common/business_components/src/ui/search_base_form/index.tsx
+++ b/packages/common/business_components/src/ui/search_base_form/index.tsx
@@ -13,6 +13,7 @@ type SearchBaseType = {
selectMiddleRegionData?: SelectDataType[] | [];
selectEnvPartData?: EnvPartSelectDataType[] | [];
queryClick:(returnType:ReturnType) => void;
+ excelName?:string;
excelClick:(returnType:ReturnType) => void;
initClick:() => void;
btnClass:string;
@@ -39,6 +40,7 @@ function SearchBaseForm ({
selectMiddleRegionData,
selectEnvPartData,
btnClass,
+ excelName,
queryClick,
excelClick,
initClick,
@@ -120,7 +122,7 @@ function SearchBaseForm ({