diff --git a/apps/wr/app/(with-layout)/matMng/coMat/ruseCaseMng/page.tsx b/apps/wr/app/(with-layout)/matMng/coMat/ruseCaseMng/page.tsx index 2439a38e9..d76549153 100644 --- a/apps/wr/app/(with-layout)/matMng/coMat/ruseCaseMng/page.tsx +++ b/apps/wr/app/(with-layout)/matMng/coMat/ruseCaseMng/page.tsx @@ -8,7 +8,7 @@ import RuseCaseMngExcel from "@/components/ui/modal/coMat/ruseCaseMng/ruseCaseMn import type { objSearchType } from "@/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal"; import { ContentsDiv, - filePickedBlobArray, + filePickedBlobNumStyle, SearchDiv, SearchFormLeft, SearchFormRight, @@ -112,6 +112,8 @@ export default function RuseCaseMng() { if (next !== cell.v) cell.v = next; }); }); + + // 엑셀 Workbook 객체를 파일 형식으로 변환 const updatedBlob = XLSX.write(wb, { bookType: "xlsx", type: "array" }); const excelData1 = excelList.map((item) => { @@ -172,14 +174,17 @@ export default function RuseCaseMng() { const sheetParameter: SheetParameter[] = [ { data: excelData1, - headerNum: 2, + headerNum: 1, headerRange: "A1:AX1", sheetName: "물재이용사례", startCol: "A", + decimalArray0: [5,8,11,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49] }, ]; // 버퍼에 있는 엑셀데이터 전달 후 json으로 변환 - await filePickedBlobArray(updatedBlob, "물재이용사례현황", sheetParameter); + // await filePickedBlobArray(updatedBlob, "물재이용사례현황", sheetParameter); + await filePickedBlobNumStyle(updatedBlob, "물재이용사례현황", sheetParameter); + }); }, [excelList]); diff --git a/apps/wr/app/(with-layout)/ruseFcltMng/fcltSttn/htdflSttn/page.tsx b/apps/wr/app/(with-layout)/ruseFcltMng/fcltSttn/htdflSttn/page.tsx index 9d52e4b49..ec7781b49 100644 --- a/apps/wr/app/(with-layout)/ruseFcltMng/fcltSttn/htdflSttn/page.tsx +++ b/apps/wr/app/(with-layout)/ruseFcltMng/fcltSttn/htdflSttn/page.tsx @@ -9,12 +9,13 @@ import type { } from "@/app/store/ruseFcltMng/fcltReg/rainReg"; import { htdflSttnSize } from "@/app/store/ruseFcltMng/fcltSttn/htdflSttn"; import { - excelDownload, + excelDownloadNumStyle, formatArchArea, formatCommaNumber, getCity, tableData } from "@/components/lib/func/commom"; +import { type SheetParameter } from "@common/business_components/ui"; import type { objSearchType } from "@/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal"; import HeadChModal from "@/components/ui/modal/sttn/headChModal/headChModal"; import SttnDetailModal from "@/components/ui/modal/sttn/sttnDetailModal/sttnDetailModal"; @@ -113,11 +114,18 @@ export default function HtdflSttn() { return; } if (htdflSttn.excelList.length > 0) { - excelDownload( - htdflSttn.excelList, + const sheetArray: SheetParameter[] = [{ + data: htdflSttn.excelList, + headerNum: 3, + headerRange: "A1:R3", + sheetName: 'sheet1', + startCol: 'A', + decimalArray0: [6,11,13,15], // 0부터 시작 + }]; + excelDownloadNumStyle( "온배수시설 현황", "sample_htdflSttn.xlsx", - "A1:R3" + sheetArray ); } else { toast.error(t('excelDownErrMsg')); diff --git a/apps/wr/app/(with-layout)/ruseFcltMng/fcltSttn/rainSttn/page.tsx b/apps/wr/app/(with-layout)/ruseFcltMng/fcltSttn/rainSttn/page.tsx index d4658297a..2e0a84bd0 100644 --- a/apps/wr/app/(with-layout)/ruseFcltMng/fcltSttn/rainSttn/page.tsx +++ b/apps/wr/app/(with-layout)/ruseFcltMng/fcltSttn/rainSttn/page.tsx @@ -9,7 +9,7 @@ import type { } from "@/app/store/ruseFcltMng/fcltReg/rainReg"; import { rainSttnSize } from "@/app/store/ruseFcltMng/fcltSttn/rainSttn"; import { - excelDownloadStyle, + excelDownloadNumStyle, getCity, tableData, } from "@/components/lib/func/commom"; @@ -164,11 +164,10 @@ export default function RainSttn() { headerNum: 3, headerRange: "A1:W3", sheetName: 'sheet1', - writeLine: 4, startCol: 'A', - decimalArray0: [6,10,12,14,16] + decimalArray0: [6,10,12,14,16] // 0부터 시작 }]; - excelDownloadStyle( + excelDownloadNumStyle( "빗물이용시설 현황", "sample_rainSttn.xlsx", // public 폴더에 있는 template 파일 경로 sheetArray diff --git a/apps/wr/app/(with-layout)/ruseFcltMng/fcltSttn/rswtSttn/page.tsx b/apps/wr/app/(with-layout)/ruseFcltMng/fcltSttn/rswtSttn/page.tsx index 247d09c82..8ff899a28 100644 --- a/apps/wr/app/(with-layout)/ruseFcltMng/fcltSttn/rswtSttn/page.tsx +++ b/apps/wr/app/(with-layout)/ruseFcltMng/fcltSttn/rswtSttn/page.tsx @@ -7,12 +7,13 @@ import { btnClass } from "@/app/store/common/code"; import type { customRswtBdst } from "@/app/store/ruseFcltMng/fcltReg/rswtReg"; import { rswtSttnSize } from "@/app/store/ruseFcltMng/fcltSttn/rswtSttn"; import { - excelDownload, + excelDownloadNumStyle, formatArchArea, formatCommaNumber, getCity, tableData } from "@/components/lib/func/commom"; +import { type SheetParameter } from "@common/business_components/ui"; import type { objSearchType } from "@/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal"; import HeadChModal from "@/components/ui/modal/sttn/headChModal/headChModal"; import SttnDetailModal from "@/components/ui/modal/sttn/sttnDetailModal/sttnDetailModal"; @@ -128,11 +129,18 @@ export default function RswtSttn() { return; } if (rswtSttn.excelList.length > 0) { - excelDownload( - rswtSttn.excelList, + const sheetArray: SheetParameter[] = [{ + data: rswtSttn.excelList, + headerNum: 3, + headerRange: "A1:W3", + sheetName: 'sheet1', + startCol: 'A', + decimalArray0: [6,10,12,16], // 0부터 시작 + }]; + excelDownloadNumStyle( "중수도시설 현황", "sample_rswtSttn.xlsx", - "A1:W3", + sheetArray ); } else { toast.error(t('excelDownErrMsg')); diff --git a/apps/wr/app/(with-layout)/ruseFcltMng/prfmncSttn/chkgdnSttn/page.tsx b/apps/wr/app/(with-layout)/ruseFcltMng/prfmncSttn/chkgdnSttn/page.tsx index fdc4d9c14..d45a646a4 100644 --- a/apps/wr/app/(with-layout)/ruseFcltMng/prfmncSttn/chkgdnSttn/page.tsx +++ b/apps/wr/app/(with-layout)/ruseFcltMng/prfmncSttn/chkgdnSttn/page.tsx @@ -4,7 +4,8 @@ import { useWrStore } from "@/app/store"; import { btnClass } from "@/app/store/common/code"; import { rainPageSize } from "@/app/store/prfmncReg/chkgdnReg/rainChkgdn"; import { rswtPageSize } from "@/app/store/prfmncReg/chkgdnReg/rswrtChkgdn"; -import { excelDownload, yearOptions } from "@/components/lib/func/commom"; +import { excelDownloadNumStyle, yearOptions } from "@/components/lib/func/commom"; +import { type SheetParameter } from "@common/business_components/ui"; import ChkgdModal from "@/components/ui/modal/chkgd/chkgdModal/chkgdModal"; import RainChkgdTable from "@/components/ui/table/chkgdTable/rainChkgd/rainChkgdTable"; import RswtChkgdTable from "@/components/ui/table/chkgdTable/rswtChkgd/rswtChkgdTable"; @@ -145,12 +146,18 @@ export default function Page() { toast.error(t("excelDownErrMsg")); return; } - excelDownload( - rainChkSttn.sttnExcelList, + const sheetArray: SheetParameter[] = [{ + data: rainChkSttn.sttnExcelList, + headerNum: 2, + headerRange: "A1:Q2", + sheetName: 'sheet1', + startCol: 'A', + decimalArray0: [5,6,7,9,10,11,12,13,16], // 0부터 시작 + }]; + excelDownloadNumStyle( "빗물이용시설 지도점검 현황", "sample_rainChkSttn.xlsx", - "A1:Q2", - 3 + sheetArray ); } else if (rswtChkSttn.sttnExcelList && selFcltDiv === "RST") { if ( @@ -160,12 +167,18 @@ export default function Page() { toast.error(t("excelDownErrMsg")); return; } - excelDownload( - rswtChkSttn.sttnExcelList, + const sheetArray: SheetParameter[] = [{ + data: rswtChkSttn.sttnExcelList, + headerNum: 2, + headerRange: "A1:X2", + sheetName: 'sheet1', + startCol: 'A', + decimalArray0: [4,5,9,10,11,12,13,14,17,18,19,23], // 0부터 시작 + }]; + excelDownloadNumStyle( "중수도시설 지도점검 현황", "sample_rswtChkSttn.xlsx", - "A1:X2", - 3 + sheetArray ); } }; diff --git a/apps/wr/app/(with-layout)/ruseFcltMng/prfmncSttn/pbnstPrfmncSttn/page.tsx b/apps/wr/app/(with-layout)/ruseFcltMng/prfmncSttn/pbnstPrfmncSttn/page.tsx index 685858262..8165c834d 100644 --- a/apps/wr/app/(with-layout)/ruseFcltMng/prfmncSttn/pbnstPrfmncSttn/page.tsx +++ b/apps/wr/app/(with-layout)/ruseFcltMng/prfmncSttn/pbnstPrfmncSttn/page.tsx @@ -4,7 +4,8 @@ import { useWrStore } from "@/app/store"; import { btnClass } from "@/app/store/common/code"; import { initValInUsage, initValOutUsage, subTotalObj, totalObj, type FcPrfType, type PrfType } from "@/app/store/prfmncReg/pbnstPrfmncReg/type"; import { excelPrfmncSttnParsing } from "@/app/store/prfmncSttn/pbnstPrfmncSttn/excel"; -import { excelDownload, yearOptions } from "@/components/lib/func/commom"; +import { excelDownloadNumStyle, yearOptions } from "@/components/lib/func/commom"; +import { type SheetParameter } from "@common/business_components/ui"; import { InputTableBody } from "@/components/lib/func/TableData"; import { CHART_FORM, ContentsDiv, MainChart, ScrollArea, SearchBaseForm, SearchInput, SelectBox, UiTable, type ChartConfig, type ReturnType } from "@common/business_components"; import ListDiv from "@common/business_components/ui/list_div"; @@ -46,12 +47,18 @@ export default function PbnstPrfmncSttn() { toast.error(t('excelDownErrMsg')); return; } - excelDownload( - excelData, + const sheetArray: SheetParameter[] = [{ + data: excelData, + headerNum: 1, + headerRange: "A1:N1", + sheetName: 'sheet1', + startCol: 'A', + decimalArray0: [1,2,3,4,5,6,7,8,9,10,11,12,13], // 0부터 시작 + }]; + excelDownloadNumStyle( "하수재이용실적 현황", "sample_pbnstPrfmncSttn.xlsx", - "A1:N1", - 2 + sheetArray ); }, [excelData]); const [chartConfig, setChartConfig] = useState({}); diff --git a/apps/wr/app/(with-layout)/stats/rainStat/page.tsx b/apps/wr/app/(with-layout)/stats/rainStat/page.tsx index d0a5cef67..2cf0585be 100644 --- a/apps/wr/app/(with-layout)/stats/rainStat/page.tsx +++ b/apps/wr/app/(with-layout)/stats/rainStat/page.tsx @@ -3,8 +3,9 @@ import { useWrStore } from "@/app/store"; import { btnClass } from "@/app/store/common/code"; import type { RainStatProps } from "@/app/store/stats/rainStat"; -import { excelDownload, tableData, yearOptions } from "@/components/lib/func/commom"; -import { downloadExcel } from "@common/business_components"; +import { excelDownloadNumStyle, tableData, yearOptions } from "@/components/lib/func/commom"; +import { type SheetParameter } from "@common/business_components/ui"; +import { downloadExcelFormat } from "@common/business_components"; import { ContentsDiv, @@ -140,13 +141,19 @@ export default function RainStat() { const excelData = [...sidoTotalSummary, ...sidoSummaryList, ...summaryExcelData]; - console.log(' excelData ', excelData) - excelDownload( - excelData as unknown as [][], + // console.log(' excelData ', excelData); + const sheetArray: SheetParameter[] = [{ + data: excelData, + headerNum: 3, + headerRange: "A1:O3", + sheetName: 'sheet1', + startCol: 'A', + decimalArray0: [1,2,3,4,5,6,7,8,9,10,11,12], // 0부터 시작 + }]; + excelDownloadNumStyle( "빗물이용시설 통계", "sample_rainStats.xlsx", - "A1:O3", - 4 + sheetArray ); } @@ -169,11 +176,12 @@ export default function RainStat() { "연간운영비(백만원/년)": item.anlOperCst, }; }) - downloadExcel({ + downloadExcelFormat({ data: (tbData as unknown as JSON[]) ?? [], fileName: "재이용통계", sheetNameArray: ["Sheet1"], - headerRange: "A1:M1" + headerRange: "A1:M1", + decimalArray0: [1,2,3,4,5,6,7,8,9,10,11,12], // 0부터 시작 }) }else{ toast.error(t('excelDownErrMsg')); diff --git a/apps/wr/app/(with-layout)/stats/rswtStat/page.tsx b/apps/wr/app/(with-layout)/stats/rswtStat/page.tsx index 3c4478e7e..5f34a73d4 100644 --- a/apps/wr/app/(with-layout)/stats/rswtStat/page.tsx +++ b/apps/wr/app/(with-layout)/stats/rswtStat/page.tsx @@ -2,10 +2,11 @@ import { useWrStore } from "@/app/store"; import { btnClass } from "@/app/store/common/code"; import type { RswtStatProps } from "@/app/store/stats/rswtStat"; -import { excelDownload, tableData, yearOptions } from "@/components/lib/func/commom"; +import { excelDownloadNumStyle, tableData, yearOptions } from "@/components/lib/func/commom"; +import { type SheetParameter } from "@common/business_components/ui"; +import { downloadExcelFormat } from "@common/business_components"; import { ContentsDiv, - downloadExcel, ScrollArea, SearchDiv, SelectBox, @@ -53,11 +54,12 @@ export default function RswtStat() { }; }) - downloadExcel({ + downloadExcelFormat({ data: (data as unknown as JSON[]) ?? [], fileName: "중수도재이용통계", sheetNameArray: ["Sheet1"], - headerRange: "A1:N1" + headerRange: "A1:N1", + decimalArray0: [1,2,3,4,5,6,7,8,9,10,11,12,13], // 0부터 시작 }) } else { toast.error(t("excelDownErrMsg")) @@ -220,12 +222,18 @@ export default function RswtStat() { // sidoSummaryList와 rainDetailList를 합쳐서 엑셀 데이터 생성 const excelData = [...sidoTotalSummary, ...sidoSummaryList, ...summaryExcelData]; - excelDownload( - excelData as unknown as [][], + const sheetArray: SheetParameter[] = [{ + data: excelData, + headerNum: 3, + headerRange: "A1:P3", + sheetName: 'sheet1', + startCol: 'A', + decimalArray0: [1,2,3,4,5,6,7,8,9,10,11,12], // 0부터 시작 + }]; + excelDownloadNumStyle( "중수도시설 통계", "sample_rswtStats.xlsx", - "A1:P3", - 4 + sheetArray ); } diff --git a/apps/wr/components/lib/func/commom.tsx b/apps/wr/components/lib/func/commom.tsx index ff0082434..e8a034b62 100644 --- a/apps/wr/components/lib/func/commom.tsx +++ b/apps/wr/components/lib/func/commom.tsx @@ -2,14 +2,12 @@ import { lwCds, type comCodeState } from "@/app/store/common/code"; import { filePickedBlob, filePickedBlobArray, - filePickedBlobArrayFormat, filePickedBlobNumStyle, type ReturnType, type SelectDataType, type SheetParameter, } from "@common/business_components/ui"; import { Button } from "@common/components/ui"; -import { write } from "fs"; import moment from "moment"; import type { RefObject } from "react"; import toast from "react-hot-toast"; @@ -103,22 +101,19 @@ export const excelDownload = ( }); }; -export const excelDownloadStyle = ( - // excelList: [][], +export const excelDownloadNumStyle = ( fileNm: string, sampleFile: string, sheetArray: SheetParameter[] ) => { // if (excelList.length === 0) return; - fetch(`/${sampleFile}`, {}).then(async (response) => { + fetch(`/${sampleFile}`, {}).then(async (response) => { // excel Tamplate을 읽는다. if (!response.ok) { throw Error(response.statusText); } // 받은 파일 바인너리 처리 const blobRet = await response.arrayBuffer(); // 버퍼에 있는 엑셀데이터 전달 후 json으로 변환 - // await filePickedBlob(blobRet, excelList, fileNm, writeLine, headerRange); - await filePickedBlobNumStyle(blobRet, fileNm, sheetArray); }); }; diff --git a/packages/common/business_components/src/ui/excel/index.tsx b/packages/common/business_components/src/ui/excel/index.tsx index a532e948e..23dfd0fea 100644 --- a/packages/common/business_components/src/ui/excel/index.tsx +++ b/packages/common/business_components/src/ui/excel/index.tsx @@ -18,11 +18,10 @@ type ExcelDownloadProps = { } export type SheetParameter = { - data: any[][]; + data: unknown[][]; headerNum: number; headerRange: string; sheetName: string; - writeLine?: number; startCol?: string; decimalArray0?: number[]; decimalArray1?: number[]; @@ -46,7 +45,7 @@ export const applyRangeFormat = ( .map((part) => part.trim()) .filter(Boolean); for (const part of parts) { - const rangeInfo = XLSX.utils.decode_range(part); + const rangeInfo = XLSX.utils.decode_range(part); // 셀 범위 문자열(ex. A1:D10)을 행/열 인덱스 객체로 변환 for (let row = rangeInfo.s.r; row <= rangeInfo.e.r; row++) { for (let col = rangeInfo.s.c; col <= rangeInfo.e.c; col++) { const cellAddr = XLSX.utils.encode_cell({ r: row, c: col }); @@ -149,21 +148,21 @@ export const downloadExcelFormat = ({ 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]); - console.log('decimalArray0 : ', decimalArray0); + // console.log('decimalArray0 : ', decimalArray0); const headerEnd = XLSX.utils.decode_range(headerRange).e.r; // 0-based index const startRow = headerEnd + 1; // 🔹 전체 범위 const range = XLSX.utils.decode_range(worksheet["!ref"] as string); - applyDecimalColumns(worksheet, startRow, range, decimalArray0, 0); - applyDecimalColumns(worksheet, startRow, range, decimalArray1, 1); - applyDecimalColumns(worksheet, startRow, range, decimalArray2, 2); - applyDecimalColumns(worksheet, startRow, range, decimalArray3, 3); - applyRangeFormat(worksheet, decimalRange0, 0); - applyRangeFormat(worksheet, decimalRange1, 1); - applyRangeFormat(worksheet, decimalRange2, 2); - applyRangeFormat(worksheet, decimalRange3, 3); + if(decimalArray0) {applyDecimalColumns(worksheet, startRow, range, decimalArray0, 0);} + if(decimalArray1) {applyDecimalColumns(worksheet, startRow, range, decimalArray1, 1);} + if(decimalArray2) {applyDecimalColumns(worksheet, startRow, range, decimalArray2, 2);} + if(decimalArray3) {applyDecimalColumns(worksheet, startRow, range, decimalArray3, 3);} + if(decimalRange0) {applyRangeFormat(worksheet, decimalRange0, 0);} + if(decimalRange1) {applyRangeFormat(worksheet, decimalRange1, 1);} + if(decimalRange2) {applyRangeFormat(worksheet, decimalRange2, 2);} + if(decimalRange3) {applyRangeFormat(worksheet, decimalRange3, 3);} excelStyle(XLSX.write(workbook, { bookType: "xlsx", type: "buffer" }), headerRange, fileName); }; @@ -244,7 +243,7 @@ export const filePickedArray=(oFile: File, headerNum:number=0):Promise