diff --git a/apps/fo/app/pages/(with-layout)/processFacility/page.tsx b/apps/fo/app/pages/(with-layout)/processFacility/page.tsx index efa7b8a53..302a4e8b7 100644 --- a/apps/fo/app/pages/(with-layout)/processFacility/page.tsx +++ b/apps/fo/app/pages/(with-layout)/processFacility/page.tsx @@ -7,7 +7,8 @@ "use client" import UnderComment from "@/app/components/common/UnderComment"; import { StoreContext, useFoStore } from "@/app/store"; -import { ContentsDiv, downloadExcelFormat, MainDiv, SearchBaseForm, SearchInput, SelectBox, UiModal, UiTable, type ReturnType } from "@common/business_components"; +import { ContentsDiv, downloadExcelFormat, MainDiv, SearchBaseForm, SearchInput, SelectBox + , UiModal, UiTable, type ReturnType } from "@common/business_components"; import ListDiv from "@common/business_components/ui/list_div"; import LoadingOverlay from "@common/business_components/ui/loadingBar"; import { useCallback, useContext, useEffect, useRef, useState } from "react"; 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/fcltReg/htdflReg/page.tsx b/apps/wr/app/(with-layout)/ruseFcltMng/fcltReg/htdflReg/page.tsx index d2a0849c6..92abc7d24 100644 --- a/apps/wr/app/(with-layout)/ruseFcltMng/fcltReg/htdflReg/page.tsx +++ b/apps/wr/app/(with-layout)/ruseFcltMng/fcltReg/htdflReg/page.tsx @@ -3,7 +3,7 @@ import { useWrStore } from "@/app/store"; import { btnClass } from "@/app/store/common/code"; import type { customHtdflBdst } from "@/app/store/ruseFcltMng/fcltReg/htdflReg"; -import { tableData } from "@/components/lib/func/commom"; +import { formatArchArea, tableData } from "@/components/lib/func/commom"; import HtdflRegForm from "@/components/ui/form/fcltReg/htdflReg/htdflRegForm"; import { BdstReg } from "@/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal"; import { @@ -58,14 +58,9 @@ export default function Home() { if (htdflRes && htdflRes.length > 0) { const htdflData = tableData(htdflRes, { code }).map( (item: customHtdflBdst) => { - const archArea = - item?.archArea.split(".")[0] !== "-1" - ? item?.archArea.split(".")[0] - : "확인불가"; - return { ...item, - archArea: archArea, + archArea: formatArchArea(item?.archArea, 1), cityText: item.ctpvCd === 0 ? "세종특별자치시" : (item as any).cityText, sggText: (item as any).sggText === "없음" ? "-" : (item as any).sggText, }; diff --git a/apps/wr/app/(with-layout)/ruseFcltMng/fcltReg/rswtReg/page.tsx b/apps/wr/app/(with-layout)/ruseFcltMng/fcltReg/rswtReg/page.tsx index e49e706be..1c7f38926 100644 --- a/apps/wr/app/(with-layout)/ruseFcltMng/fcltReg/rswtReg/page.tsx +++ b/apps/wr/app/(with-layout)/ruseFcltMng/fcltReg/rswtReg/page.tsx @@ -5,7 +5,7 @@ import { rswtRegSize, type customRswtBdst, } from "@/app/store/ruseFcltMng/fcltReg/rswtReg"; -import { tableData } from "@/components/lib/func/commom"; +import { formatArchArea, tableData } from "@/components/lib/func/commom"; import RswtrRegForm from "@/components/ui/form/fcltReg/rswtrReg/rswtrRegForm"; import { BdstReg } from "@/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal"; import { @@ -71,13 +71,9 @@ export default function Home() { if (rswtRes?.length > 0) { const rswtData = tableData(rswtRes, { code })?.map( (item: customRswtBdst) => { - const archArea = - item?.archArea.split(".")[0] !== "-1" - ? item?.archArea.split(".")[0] - : "확인불가"; return { ...item, - archArea: archArea, + archArea: formatArchArea(item?.archArea, 1), bdstChgYn: item.chgBuilding[0]?.bdstChgNm != null ? "Y" : "N", bdstUsgCd: item.reuseBuilding[0]?.bdstUsgCd, cityText: item.ctpvCd === 0 ? "세종특별자치시" : (item as any).cityText, 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 beebe58d4..c17b7dca8 100644 --- a/apps/wr/app/(with-layout)/ruseFcltMng/fcltSttn/htdflSttn/page.tsx +++ b/apps/wr/app/(with-layout)/ruseFcltMng/fcltSttn/htdflSttn/page.tsx @@ -9,10 +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"; @@ -111,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')); @@ -137,6 +147,11 @@ export default function HtdflSttn() { ...item.reuseBuilding[0], ...item.reuseBuilding[0].htdflObj, chBuildingYn: item.chgBuilding[0]?.bdstChgNm !== null ? "Y" : "N", + archArea: formatArchArea(item?.archArea, 1), + prcsFcltCpct: + Number(item.reuseBuilding[0]?.htdflObj?.prcsFcltCpct) === -1 + ? "확인불가" + : formatCommaNumber(item.reuseBuilding[0]?.htdflObj?.prcsFcltCpct), })) .filter((item: any) => item.htdflObj !== undefined); setBdstTable(chData); @@ -213,20 +228,24 @@ export default function HtdflSttn() {
- { - cellClick(index ?? undefined, headId); - }} - onPageChange={setPageNation} - resetPageNo={resetPage} - > - - +
+
+ { + cellClick(index ?? undefined, headId); + }} + onPageChange={setPageNation} + resetPageNo={resetPage} + > + + +
+
diff --git a/apps/wr/app/(with-layout)/ruseFcltMng/fcltSttn/pbnstSttn/page.tsx b/apps/wr/app/(with-layout)/ruseFcltMng/fcltSttn/pbnstSttn/page.tsx index fd573ef99..ecedeb426 100644 --- a/apps/wr/app/(with-layout)/ruseFcltMng/fcltSttn/pbnstSttn/page.tsx +++ b/apps/wr/app/(with-layout)/ruseFcltMng/fcltSttn/pbnstSttn/page.tsx @@ -13,7 +13,8 @@ import { btnClass } from "@/app/store/common/code"; import { prfRegPageSize } from "@/app/store/prfmncReg/pbnstPrfmncReg"; import type { customPbnst } from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type"; import type { WaterReuseFacility } from "@/app/store/ruseFcltMng/fcltSttn/pbnstSttn/type"; -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 HeadChModal from "@/components/ui/modal/sttn/headChModal/headChModal"; import { PbnstSttnModal } from "@/components/ui/modal/sttn/pbnstSttnModal/pbnstSttnModal"; import { @@ -103,13 +104,19 @@ export default function PbnstSttn() { if (!isDownloadTriggered.current) { return; } + const sheetArray: SheetParameter[] = [{ + data: pbnstSttn.excelList, + headerNum: 2, + headerRange: "A1:U2", + sheetName: 'sheet1', + startCol: 'A', + decimalArray0: [9,11,12,13,14,15,16] // 0부터 시작 + }]; if (pbnstSttn.excelList.length > 0) { - excelDownload( - pbnstSttn.excelList, + excelDownloadNumStyle( "하수재이용시설 현황", "sample_pbnstSttn.xlsx", - "A1:U2", - 3 + sheetArray ); } else { toast.error(t("excelDownErrMsg")); @@ -195,31 +202,35 @@ export default function PbnstSttn() {
- { - cellCLick(index); - }} - onPageChange={(page: number) => { - pbnstSttnSearch( - false, - String(page), - String(prfRegPageSize), - ref.current, - pbnRuseNm, - searchYear, - fclts - ); - setIsReset(false); - }} - resetPageNo={isReset} - > - - +
+
+ { + cellCLick(index); + }} + onPageChange={(page: number) => { + pbnstSttnSearch( + false, + String(page), + String(prfRegPageSize), + ref.current, + pbnRuseNm, + searchYear, + fclts + ); + setIsReset(false); + }} + resetPageNo={isReset} + > + + +
+
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 029f19852..750491f8d 100644 --- a/apps/wr/app/(with-layout)/ruseFcltMng/fcltSttn/rainSttn/page.tsx +++ b/apps/wr/app/(with-layout)/ruseFcltMng/fcltSttn/rainSttn/page.tsx @@ -9,10 +9,11 @@ import type { } from "@/app/store/ruseFcltMng/fcltReg/rainReg"; import { rainSttnSize } from "@/app/store/ruseFcltMng/fcltSttn/rainSttn"; import { - excelDownload, + excelDownloadNumStyle, 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"; @@ -158,11 +159,18 @@ export default function RainSttn() { return; } if (rainSttn.excelList.length > 0) { - excelDownload( - rainSttn.excelList, + const sheetArray: SheetParameter[] = [{ + data: rainSttn.excelList, + headerNum: 3, + headerRange: "A1:W3", + sheetName: 'sheet1', + startCol: 'A', + decimalArray0: [6,10,12,14,16] // 0부터 시작 + }]; + excelDownloadNumStyle( "빗물이용시설 현황", - "sample_rainSttn.xlsx", - "A1:W3" + "sample_rainSttn.xlsx", // public 폴더에 있는 template 파일 경로 + sheetArray ); } else { toast.error(t("excelDownErrMsg")); @@ -265,20 +273,24 @@ export default function RainSttn() {
- { - cellClick(index ?? undefined); - }} - onPageChange={setPageNation} - resetPageNo={resetPage} - > - - +
+
+ { + cellClick(index ?? undefined); + }} + onPageChange={setPageNation} + resetPageNo={resetPage} + > + + +
+
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 fb1aecd7d..0392c8f3f 100644 --- a/apps/wr/app/(with-layout)/ruseFcltMng/fcltSttn/rswtSttn/page.tsx +++ b/apps/wr/app/(with-layout)/ruseFcltMng/fcltSttn/rswtSttn/page.tsx @@ -7,10 +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"; @@ -106,7 +109,11 @@ export default function RswtSttn() { chBuildingYn: item?.chgBuilding[0]?.bdstChgNm !== null && item?.chgBuilding.length > 0 ? 'Y' : 'N', instlCst: item.reuseBuilding[0]?.instlCst === -1 ? "확인불가" : item.reuseBuilding[0]?.instlCst, instlCstSprtAmt: item.reuseBuilding[0]?.instlCstSprtAmt === -1 ? "확인불가" : item.reuseBuilding[0]?.instlCstSprtAmt, - archArea: item?.archArea.split('.')[0] !== '-1' ? item?.archArea.split('.')[0] : '확인불가', + archArea: formatArchArea(item?.archArea, 1), + filtrTrtmfctCpct: + Number(item.reuseBuilding[0]?.rswtrObj?.filtrTrtmfctCpct) === -1 + ? "확인불가" + : formatCommaNumber(item.reuseBuilding[0]?.rswtrObj?.filtrTrtmfctCpct), } }) .filter( @@ -122,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')); @@ -218,18 +232,22 @@ export default function RswtSttn() {
- { cellClick(index ?? undefined) }} - onPageChange={setPageNation} - resetPageNo={resetPage} - > - - +
+
+ { cellClick(index ?? undefined) }} + onPageChange={setPageNation} + resetPageNo={resetPage} + > + + +
+
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..b5ba8cfff 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 ); } }; @@ -248,29 +261,33 @@ export default function Page() {
- {selFcltDiv === "RNB" ? ( - {}} - detailUp={() => {}} - handleClick={handleClick} - rainChkData={rainChkSttn.rainChkRes} - pageNation={rainPageNation} - onPageChange={rainPageChange} - pageCount={rainChkSttn.rainChkCount} - readonly={true} - /> - ) : ( - {}} - deleteRswtData={() => {}} - handleRswtClick={handleClick} - rswtChkData={rswtChkSttn.rswtChkRes} - pageNation={rswtPageNation} - onPageChange={rswtPageChange} - pageCount={rswtChkSttn.rswtChkCount} - readonly={true} - /> - )} +
+
+ {selFcltDiv === "RNB" ? ( + {}} + detailUp={() => {}} + handleClick={handleClick} + rainChkData={rainChkSttn.rainChkRes} + pageNation={rainPageNation} + onPageChange={rainPageChange} + pageCount={rainChkSttn.rainChkCount} + readonly={true} + /> + ) : ( + {}} + deleteRswtData={() => {}} + handleRswtClick={handleClick} + rswtChkData={rswtChkSttn.rswtChkRes} + pageNation={rswtPageNation} + onPageChange={rswtPageChange} + pageCount={rswtChkSttn.rswtChkCount} + readonly={true} + /> + )} +
+
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/app/store/ruseFcltMng/fcltSttn/pbnstSttn/headList.tsx b/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/headList.tsx index a1d1193b2..ac766b0b3 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/headList.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/headList.tsx @@ -7,27 +7,11 @@ import { z } from "zod"; export const pbnSttHeadListExport: z.infer = [ { id: "rvbsn", title: "권역", visible: true }, - { - id: "lgbsn", - title: "단위유역", - visible: true, - }, - { - id: "mdmbsn", - title: "중권역", - visible: true, - }, + { id: "lgbsn", title: "단위유역", visible: true, }, + { id: "mdmbsn", title: "중권역", visible: true, }, { id: "rgnNm", title: "환경청", visible: true }, - { - id: "sido", - title: "시도", - visible: true, - }, - { - id: "gugun", - title: "시군구", - visible: true, - }, + { id: "sido", title: "시도", visible: true, }, + { id: "gugun", title: "시군구", visible: true, }, { id: "bscFctNm", title: "시설명", visible: true }, { id: "efflWqltStndrdNm", title: "지역구분", visible: true }, @@ -35,405 +19,69 @@ export const pbnSttHeadListExport: z.infer = [ { id: "fctCpc", title: "시설용량(톤/일)", visible: true }, { id: "ruseUtztnFcltNm", title: "재이용시설명", visible: true }, - { - id: "fcltCpct", - title: "시설용량(m³/일)", - visible: true, - }, - { - id: "splyExtraCpct", - title: "하수처리량(m³/일)", - visible: true, - }, - { - id: "ruseCpct", - title: "재이용량(m³/일)", - visible: true, - }, + { id: "fcltCpct", title: "시설용량(m³/일)", visible: true, }, + { id: "splyExtraCpct", title: "하수처리량(m³/일)", visible: true, }, + { id: "ruseCpct", title: "재이용량(m³/일)", visible: true, }, - { - id: "usageTotal", - title: "합계", - visible: true, - }, - { - id: "inUsage", - title: "장내용수", - visible: true, - }, - { - id: "outUsage", - title: "장외용수", - visible: true, - }, + { id: "usageTotal", title: "합계", visible: true, }, + { id: "inUsage", title: "장내용수", visible: true, }, + { id: "outUsage", title: "장외용수", visible: true, }, - { - id: "operMthd", - title: "운영방식", - visible: true, - }, - { - id: "rprtvBzenty", - title: "대행업체", - visible: true, - }, - { - id: "bgngDt", - title: "시작일", - visible: true, - }, - { - id: "endDt", - title: "종료일", - visible: true, - }, + { id: "operMthd", title: "운영방식", visible: true, }, + { id: "rprtvBzenty", title: "대행업체", visible: true, }, + { id: "bgngDt", title: "시작일", visible: true, }, + { id: "endDt", title: "종료일", visible: true, }, ]; // id는 다확인해야함 export const pbnstSttNodeListExport: CommonTableProps[] = [ - { - id: "catchment", - title: "유역", - visible: true, - row: 1, - rowSpan: 1, - colSpan: 3, - }, - { - id: "rgnNm", - title: "환경청", - visible: true, - row: 1, - rowSpan: 2, - colSpan: 1, - }, - { - id: "adminDiv", - title: "행정구역", - visible: true, - row: 1, - rowSpan: 1, - colSpan: 2, - }, - { - id: "bscFctNm", - title: "시설명", - visible: true, - row: 1, - rowSpan: 2, - colSpan: 1, - }, - { - id: "efflWqltStndrdNm", - title: "지역구분", - visible: true, - row: 1, - rowSpan: 2, - colSpan: 1, - }, - { - id: "tel", - title: "전화번호", - visible: true, - row: 1, - rowSpan: 2, - colSpan: 1, - }, - { - id: "fctCpc", - title: "시설용량(m³/일)", - visible: true, - row: 1, - rowSpan: 2, - colSpan: 1, - }, - { - id: "ruseUtztnFcltNm", - title: "재이용시설명", - visible: true, - row: 1, - rowSpan: 2, - colSpan: 1, - }, - { - id: "rusSup", - title: "재이용수공급가능량(m³/일)", - visible: true, - row: 1, - rowSpan: 1, - colSpan: 3, - }, - { - id: "yearResult", - title: "연간실적정보(m³)", - visible: true, - row: 1, - rowSpan: 1, - colSpan: 3, - }, - { - id: "mngInfo", - title: "운영정보", - visible: true, - row: 1, - rowSpan: 1, - colSpan: 4, - }, - { - id: "rvbsn", - title: "권역", - upName: "catchment", - visible: true, - row: 2, - rowSpan: 1, - colSpan: 1, - }, - { - id: "lgbsn", - title: "단위유역", - upName: "catchment", - visible: true, - row: 2, - rowSpan: 1, - colSpan: 1, - }, - { - id: "mdmbsn", - title: "중권역", - upName: "catchment", - visible: true, - row: 2, - rowSpan: 1, - colSpan: 1, - }, - { - id: "sido", - title: "시도", - upName: "adminDiv", - visible: true, - row: 2, - rowSpan: 1, - colSpan: 1, - }, - { - id: "gugun", - title: "시군구", - upName: "adminDiv", - visible: true, - row: 2, - rowSpan: 1, - colSpan: 1, - }, - { - id: "fcltCpct", - title: "시설용량", - upName: "rusSup", - visible: true, - row: 2, - rowSpan: 1, - colSpan: 1, - }, - { - id: "splyExtraCpct", - title: "하수처리량", - upName: "rusSup", - visible: true, - row: 2, - rowSpan: 1, - colSpan: 1, - }, - { - id: "ruseCpct", - title: "재이용량", - upName: "rusSup", - visible: true, - row: 2, - rowSpan: 1, - colSpan: 1, - }, - { - id: "usageTotal", - title: "합계", - upName: "yearResult", - visible: true, - row: 2, - rowSpan: 1, - colSpan: 1, - }, - { - id: "inUsage", - title: "장내용수", - upName: "yearResult", - visible: true, - row: 2, - rowSpan: 1, - colSpan: 1, - }, - { - id: "outUsage", - title: "장외용수", - upName: "yearResult", - visible: true, - row: 2, - rowSpan: 1, - colSpan: 1, - }, - { - id: "operMthd", - title: "운영방식", - upName: "mngInfo", - visible: true, - row: 2, - rowSpan: 1, - colSpan: 1, - }, - { - id: "rprtvBzenty", - title: "대행업체", - upName: "mngInfo", - visible: true, - row: 2, - rowSpan: 1, - colSpan: 1, - }, - { - id: "bgngDt", - title: "시작일", - upName: "mngInfo", - visible: true, - row: 2, - rowSpan: 1, - colSpan: 1, - }, - { - id: "endDt", - title: "종료일", - upName: "mngInfo", - visible: true, - row: 2, - rowSpan: 1, - colSpan: 1, - }, + { id: "catchment", title: "유역", visible: true, row: 1, rowSpan: 1, colSpan: 3, }, + { id: "rgnNm", title: "환경청", visible: true, row: 1, rowSpan: 2, colSpan: 1, }, + { id: "adminDiv", title: "행정구역", visible: true, row: 1, rowSpan: 1, colSpan: 2, }, + { id: "bscFctNm", title: "시설명", visible: true, row: 1, rowSpan: 2, colSpan: 1, }, + { id: "efflWqltStndrdNm", title: "지역구분", visible: true, row: 1, rowSpan: 2, colSpan: 1, }, + { id: "tel", title: "전화번호", visible: true, row: 1, rowSpan: 2, colSpan: 1, }, + { id: "fctCpc", title: "시설용량(m³/일)", visible: true, row: 1, rowSpan: 2, colSpan: 1, }, + { id: "ruseUtztnFcltNm", title: "재이용시설명", visible: true, row: 1, rowSpan: 2, colSpan: 1, }, + { id: "rusSup", title: "재이용수공급가능량(m³/일)", visible: true, row: 1, rowSpan: 1, colSpan: 3, }, + { id: "yearResult", title: "연간실적정보(m³)", visible: true, row: 1, rowSpan: 1, colSpan: 3, }, + { id: "mngInfo", title: "운영정보", visible: true, row: 1, rowSpan: 1, colSpan: 4, }, + { id: "rvbsn", title: "권역", upName: "catchment", visible: true, row: 2, rowSpan: 1, colSpan: 1, }, + { id: "lgbsn", title: "단위유역", upName: "catchment", visible: true, row: 2, rowSpan: 1, colSpan: 1, }, + { id: "mdmbsn", title: "중권역", upName: "catchment", visible: true, row: 2, rowSpan: 1, colSpan: 1, }, + { id: "sido", title: "시도", upName: "adminDiv", visible: true, row: 2, rowSpan: 1, colSpan: 1, }, + { id: "gugun", title: "시군구", upName: "adminDiv", visible: true, row: 2, rowSpan: 1, colSpan: 1, }, + { id: "fcltCpct", title: "시설용량", upName: "rusSup", visible: true, row: 2, rowSpan: 1, colSpan: 1, }, + { id: "splyExtraCpct", title: "하수처리량", upName: "rusSup", visible: true, row: 2, rowSpan: 1, colSpan: 1, }, + { id: "ruseCpct", title: "재이용량", upName: "rusSup", visible: true, row: 2, rowSpan: 1, colSpan: 1, }, + { id: "usageTotal", title: "합계", upName: "yearResult", visible: true, row: 2, rowSpan: 1, colSpan: 1, }, + { id: "inUsage", title: "장내용수", upName: "yearResult", visible: true, row: 2, rowSpan: 1, colSpan: 1, }, + { id: "outUsage", title: "장외용수", upName: "yearResult", visible: true, row: 2, rowSpan: 1, colSpan: 1, }, + { id: "operMthd", title: "운영방식", upName: "mngInfo", visible: true, row: 2, rowSpan: 1, colSpan: 1, }, + { id: "rprtvBzenty", title: "대행업체", upName: "mngInfo", visible: true, row: 2, rowSpan: 1, colSpan: 1, }, + { id: "bgngDt", title: "시작일", upName: "mngInfo", visible: true, row: 2, rowSpan: 1, colSpan: 1, }, + { id: "endDt", title: "종료일", upName: "mngInfo", visible: true, row: 2, rowSpan: 1, colSpan: 1, }, ]; export const ruseFcltNodeListExport: TableUpperProps[] = [ { id: "cycl", title: "차수", visible: true, row: 1, rowSpan: 3, colSpan: 1 }, { id: "seCd", title: "구분", visible: true, row: 1, rowSpan: 3, colSpan: 1 }, - { - id: "busiTotal", - title: "사업개요", - visible: true, - row: 1, - rowSpan: 1, - colSpan: 9, - }, - { - id: "ruseFclt", - title: "재처리시설", - visible: true, - row: 1, - rowSpan: 1, - colSpan: 3, - }, - { - id: "mainSplyPumpCpct", - title: "메인공급펌프용량(m³/일)", - visible: true, - row: 1, - rowSpan: 3, - colSpan: 1, - }, - { - id: "buziFee", - title: "사업비(원)", - visible: true, - row: 2, - rowSpan: 1, - colSpan: 5, - }, - { - id: "instlAprvSncnDt", - title: "설치승인・인가일", - visible: true, - row: 2, - rowSpan: 2, - colSpan: 1, - }, - { - id: "bizCmcnDay", - title: "사업준공일", - visible: true, - row: 2, - rowSpan: 2, - colSpan: 1, - }, - { - id: "rprcsFcltCpct", - title: "시설용량(m³/일)", - visible: true, - row: 2, - rowSpan: 2, - colSpan: 1, - }, - { - id: "rprcsMthdCd", - title: "재처리방식", - visible: true, - row: 2, - rowSpan: 2, - colSpan: 1, - }, - { - id: "majorPrcsMsrcCd", - title: "주처리공법", - visible: true, - row: 2, - rowSpan: 2, - colSpan: 1, - }, - { - id: "inoutYn", - title: "위치처리장(내・외)", - visible: true, - row: 2, - rowSpan: 2, - colSpan: 1, - }, - { - id: "addr", - title: "위치(주소)", - visible: true, - row: 2, - rowSpan: 2, - colSpan: 1, - }, + { id: "busiTotal", title: "사업개요", visible: true, row: 1, rowSpan: 1, colSpan: 9 }, + { id: "ruseFclt", title: "재처리시설", visible: true, row: 1, rowSpan: 1, colSpan: 3 }, + { id: "mainSplyPumpCpct", title: "메인공급펌프용량(m³/일)", visible: true, row: 1, rowSpan: 3, colSpan: 1 }, + { id: "buziFee", title: "사업비(원)", visible: true, row: 2, rowSpan: 1, colSpan: 5 }, + { id: "instlAprvSncnDt", title: "설치승인・인가일", visible: true, row: 2, rowSpan: 2, colSpan: 1 }, + { id: "bizCmcnDay", title: "사업준공일", visible: true, row: 2, rowSpan: 2, colSpan: 1 }, + { id: "rprcsFcltCpct", title: "시설용량(m³/일)", visible: true, row: 2, rowSpan: 2, colSpan: 1 }, + { id: "rprcsMthdCd", title: "재처리방식", visible: true, row: 2, rowSpan: 2, colSpan: 1 }, + { id: "majorPrcsMsrcCd", title: "주처리공법", visible: true, row: 2, rowSpan: 2, colSpan: 1 }, + { id: "inoutYn", title: "위치처리장(내・외)", visible: true, row: 2, rowSpan: 2, colSpan: 1 }, + { id: "addr", title: "위치(주소)", visible: true, row: 2, rowSpan: 2, colSpan: 1 }, { id: "gvsbs", title: "국고", visible: true, row: 3, rowSpan: 1, colSpan: 1 }, - { - id: "lcep", - title: "지방비", - visible: true, - row: 3, - rowSpan: 1, - colSpan: 1, - }, - { - id: "cusrAlotm", - title: "민간투자비", - visible: true, - row: 3, - rowSpan: 1, - colSpan: 1, - }, - + { id: "lcep", title: "지방비", visible: true, row: 3, rowSpan: 1, colSpan: 1 }, + { id: "cusrAlotm", title: "민간투자비", visible: true, row: 3, rowSpan: 1, colSpan: 1 }, { id: "etc", title: "기타", visible: true, row: 3, rowSpan: 1, colSpan: 1 }, - { - id: "totalMoney", - title: "합계", - visible: true, - row: 3, - rowSpan: 1, - colSpan: 1, - }, + { id: "totalMoney", title: "합계", visible: true, row: 3, rowSpan: 1, colSpan: 1 }, ]; export const ruseSplyHeadListExport: TableUpperProps[] = [ @@ -481,61 +129,16 @@ export const ruseFcltHeadListExport: CommonTableProps[] = [ { id: "cycl", title: "차수", visible: true}, { id: "seCd", title: "구분", visible: true}, { id: "gvsbs", title: "국고", visible: true }, - { - id: "lcep", - title: "지방비", - visible: true, - }, - { - id: "cusrAlotm", - title: "민간투자비", - visible: true, - }, - + { id: "lcep", title: "지방비", visible: true }, + { id: "cusrAlotm", title: "민간투자비", visible: true }, { id: "etc", title: "기타", visible: true }, - { - id: "totalMoney", - title: "합계", - visible: true, - }, - { - id: "instlAprvSncnDt", - title: "설치승인・인가일", - visible: true, - }, - { - id: "bizCmcnDay", - title: "사업준공일", - visible: true, - }, - { - id: "rprcsFcltCpct", - title: "시설용량(m³/일)", - visible: true, - }, - { - id: "rprcsMthdCd", - title: "재처리방식", - visible: true, - }, - { - id: "majorPrcsMsrcCd", - title: "주처리공법", - visible: true, - }, - { - id: "inoutYn", - title: "위치처리장(내・외)", - visible: true, - }, - { - id: "addr", - title: "위치(주소)", - visible: true, - }, - { - id: "mainSplyPumpCpct", - title: "메인공급펌프용량", - visible: true, - }, + { id: "totalMoney", title: "합계", visible: true }, + { id: "instlAprvSncnDt", title: "설치승인・인가일", visible: true }, + { id: "bizCmcnDay", title: "사업준공일", visible: true }, + { id: "rprcsFcltCpct", title: "시설용량(m³/일)", visible: true }, + { id: "rprcsMthdCd", title: "재처리방식", visible: true }, + { id: "majorPrcsMsrcCd", title: "주처리공법", visible: true }, + { id: "inoutYn", title: "위치처리장(내・외)", visible: true }, + { id: "addr", title: "위치(주소)", visible: true }, + { id: "mainSplyPumpCpct", title: "메인공급펌프용량", visible: true }, ]; diff --git a/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/index.tsx b/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/index.tsx index 28743ab26..9e2c47a04 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/index.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/index.tsx @@ -166,13 +166,14 @@ export const hasuListFetch = async ( const pbnList = await postFectch( `/prcsFclt/ruseInfo/1/${filteredFclt.length}/` + url, filteredFclt, - fetchType.COMMON + fetchType.COMMON // FO ); const checkRuseFcltList = searchNm && searchNm?.length > 0 ? pbnList.data.map((item) => item.bscFctCd) : filteredFclt; + const getRuseList = await postFectch( `/reuseFc/pubDetailList/${year}/${filterData}/${page}/${total}`, checkRuseFcltList, diff --git a/apps/wr/components/lib/func/commom.tsx b/apps/wr/components/lib/func/commom.tsx index a99dd8db8..e8a034b62 100644 --- a/apps/wr/components/lib/func/commom.tsx +++ b/apps/wr/components/lib/func/commom.tsx @@ -2,6 +2,7 @@ import { lwCds, type comCodeState } from "@/app/store/common/code"; import { filePickedBlob, filePickedBlobArray, + filePickedBlobNumStyle, type ReturnType, type SelectDataType, type SheetParameter, @@ -100,6 +101,23 @@ export const excelDownload = ( }); }; +export const excelDownloadNumStyle = ( + fileNm: string, + sampleFile: string, + sheetArray: SheetParameter[] +) => { + // if (excelList.length === 0) return; + fetch(`/${sampleFile}`, {}).then(async (response) => { // excel Tamplate을 읽는다. + if (!response.ok) { + throw Error(response.statusText); + } + // 받은 파일 바인너리 처리 + const blobRet = await response.arrayBuffer(); + // 버퍼에 있는 엑셀데이터 전달 후 json으로 변환 + await filePickedBlobNumStyle(blobRet, fileNm, sheetArray); + }); +}; + export const excelArrayDownload = ( fileNm: string, sampleFile: string, diff --git a/apps/wr/public/sample_htdflSttn.xlsx b/apps/wr/public/sample_htdflSttn.xlsx index 463c1ca87..1cce66dc2 100644 Binary files a/apps/wr/public/sample_htdflSttn.xlsx and b/apps/wr/public/sample_htdflSttn.xlsx differ diff --git a/apps/wr/public/sample_pbnstSttn.xlsx b/apps/wr/public/sample_pbnstSttn.xlsx index 8bbd47ea3..ba08690d7 100644 Binary files a/apps/wr/public/sample_pbnstSttn.xlsx and b/apps/wr/public/sample_pbnstSttn.xlsx differ diff --git a/apps/wr/public/sample_rainChkSttn.xlsx b/apps/wr/public/sample_rainChkSttn.xlsx index dcab1be0c..c95ff9239 100644 Binary files a/apps/wr/public/sample_rainChkSttn.xlsx and b/apps/wr/public/sample_rainChkSttn.xlsx differ diff --git a/apps/wr/public/sample_rainStats.xlsx b/apps/wr/public/sample_rainStats.xlsx index c8f8e69b5..e2c74c12b 100644 Binary files a/apps/wr/public/sample_rainStats.xlsx and b/apps/wr/public/sample_rainStats.xlsx differ diff --git a/apps/wr/public/sample_rainSttn.xlsx b/apps/wr/public/sample_rainSttn.xlsx index f3e7a5ba8..695612251 100644 Binary files a/apps/wr/public/sample_rainSttn.xlsx and b/apps/wr/public/sample_rainSttn.xlsx differ diff --git a/apps/wr/public/sample_rswtChkSttn.xlsx b/apps/wr/public/sample_rswtChkSttn.xlsx index a5b2e85a4..4a860b3df 100644 Binary files a/apps/wr/public/sample_rswtChkSttn.xlsx and b/apps/wr/public/sample_rswtChkSttn.xlsx differ diff --git a/apps/wr/public/sample_rswtStats.xlsx b/apps/wr/public/sample_rswtStats.xlsx index bee059e26..82dad8d2b 100644 Binary files a/apps/wr/public/sample_rswtStats.xlsx and b/apps/wr/public/sample_rswtStats.xlsx differ diff --git a/apps/wr/public/sample_rswtSttn.xlsx b/apps/wr/public/sample_rswtSttn.xlsx index 1085c6cfc..9b02869d5 100644 Binary files a/apps/wr/public/sample_rswtSttn.xlsx and b/apps/wr/public/sample_rswtSttn.xlsx differ diff --git a/packages/common/business_components/src/ui/excel/index.tsx b/packages/common/business_components/src/ui/excel/index.tsx index 80acd9696..23dfd0fea 100644 --- a/packages/common/business_components/src/ui/excel/index.tsx +++ b/packages/common/business_components/src/ui/excel/index.tsx @@ -17,6 +17,104 @@ type ExcelDownloadProps = { decimalRange3?: string; } +export type SheetParameter = { + data: unknown[][]; + headerNum: number; + headerRange: string; + sheetName: string; + startCol?: string; + decimalArray0?: number[]; + decimalArray1?: number[]; + decimalArray2?: number[]; + decimalArray3?: number[]; + decimalRange0?: string; + decimalRange1?: string; + decimalRange2?: string; + decimalRange3?: string; +}; + +// Shared utility to apply number formatting to a sheet range +export const applyRangeFormat = ( + sheet: XLSX.WorkSheet, + rangeStr: string | undefined, + decimal: number +) => { + if (!rangeStr) return; + const parts = rangeStr + .split(",") + .map((part) => part.trim()) + .filter(Boolean); + for (const part of parts) { + 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 }); + const cell = sheet[cellAddr]; + if (cell) { + if (typeof cell.v === "string") { + const parsed = Number(cell.v.replace(/,/g, "").trim()); + if (!Number.isNaN(parsed)) { + cell.v = parsed; + cell.t = "n"; + } + } + } + if (cell && typeof cell.v === "number") { + if (decimal === 1) { + cell.z = "#,##0.0"; + } else if (decimal === 2) { + cell.z = "#,##0.00"; + } else if (decimal === 3) { + cell.z = "#,##0.000"; + } else { + cell.z = "#,##0"; + } + } + } + } + } +}; + + + +// Shared utility to apply decimal formatting to specific columns in a sheet +export const applyDecimalColumns = ( + sheet: XLSX.WorkSheet, + startRow: number, + range: XLSX.Range, + columns: number[], + decimal: number +) => { + for (let row = startRow; row <= range.e.r; row++) { + if (columns.length > 0) { + for (let idx = 0; idx < columns.length; idx++) { + const cellAddr = XLSX.utils.encode_cell({ r: row, c: Number(columns[idx]) }); + const cell = sheet[cellAddr]; + if (cell) { + if (typeof cell.v === "string") { + const parsed = Number(cell.v.replace(/,/g, "").trim()); + if (!Number.isNaN(parsed)) { + cell.v = parsed; + cell.t = "n"; + } + } + } + if (cell && typeof cell.v === "number") { + if (decimal === 1) { + cell.z = "#,##0.0"; // 소수점 1자리 + } else if (decimal === 2) { + cell.z = "#,##0.00"; + } else if (decimal === 3) { + cell.z = "#,##0.000"; + } else { + cell.z = "#,##0"; // 기본 천단위 콤마 + } + } + } + } + } +}; + 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(); @@ -50,78 +148,24 @@ 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); - const chaneValue = (array: number[], decimal: number) => { - for (let row = startRow; row <= range.e.r; row++) { - if(array.length>0){ - for(let idx=0; idx { - if (!rangeStr) return; - const rangeInfo = XLSX.utils.decode_range(rangeStr); - 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 }); - const cell = worksheet[cellAddr]; - if (cell && typeof cell.v === "number") { - if (decimal === 1) { - cell.z = "#,##0.0"; - } else if (decimal === 2) { - cell.z = "#,##0.00"; - } else if (decimal === 3) { - cell.z = "#,##0.000"; - } else { - cell.z = "#,##0"; - } - } - } - } - }; - chaneValue(decimalArray0, 0); - chaneValue(decimalArray1, 1); - chaneValue(decimalArray2, 2); - chaneValue(decimalArray3, 3); - applyRangeFormat(decimalRange0, 0); - applyRangeFormat(decimalRange1, 1); - applyRangeFormat(decimalRange2, 2); - applyRangeFormat(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); }; -export type SheetParameter = { - data: any[][]; - headerNum: number; - headerRange: string; - sheetName: string; - startCol?: string; - decimalRange0?: string; - decimalRange1?: string; - decimalRange2?: string; - decimalRange3?: string; -}; - export const downloadMultipleExcel = (fileName = new Date().getTime().toString() + '.xlsx', sheetArray: SheetParameter[]): Promise => { const workbook = XLSX.utils.book_new(); for (let i = 0; i < sheetArray.length; i++) { @@ -199,7 +243,7 @@ export const filePickedArray=(oFile: File, headerNum:number=0):Promise =>{ // Create A File Reader HTML5 +export const filePickedBlob = ( + oFile: ArrayBuffer, + data:[][],fileNm:string, + headerNum:number=0, + headerRange='A1:V3', + startCol?:number +):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' }); @@ -244,26 +294,57 @@ export const filePickedBlob=(oFile: ArrayBuffer, data:[][],fileNm:string, header } } }); - }); - } + }); +} +export const filePickedBlobNumStyle = async ( + oFile: ArrayBuffer, + fileNm:string, + sheetArray: SheetParameter[] +):Promise => { // Create A File Reader HTML5 + + // Ready The Event For When A File Gets Selected + const wb = XLSX.read(oFile, { type: "binary" }); + + wb.SheetNames.forEach((sheetName, index) => { + if (sheetArray[index]) { + const sheet = wb.Sheets[sheetName]; + if (sheet) { + const startCol = sheetArray[index].startCol ?? "A"; + const dataStartLine = sheetArray[index].headerNum + 1; + + // 2차원 배열(Array of Arrays, AOA) 형태의 데이터를 엑셀 시트(sheet)에 추가 + XLSX.utils.sheet_add_aoa(sheet, sheetArray[index].data, { + origin: startCol + dataStartLine, // startLine 은 1부터 시작 + }); + const startRow = Math.max(dataStartLine - 1, 0); // 행은 0부터 시작 + + // 사용된 셀 범위(range) 를 행(row)과 열(column)의 시작/끝 좌표로 변환 - 전체 범위 + const range = XLSX.utils.decode_range(sheet["!ref"] as string); // !ref - 시트에서 실제 데이터가 존재하는 영역을 의미 + + if(sheetArray[index].decimalArray0){ applyDecimalColumns(sheet, startRow, range, sheetArray[index].decimalArray0, 0); } + if(sheetArray[index].decimalArray1){ applyDecimalColumns(sheet, startRow, range, sheetArray[index].decimalArray1, 1); } + if(sheetArray[index].decimalArray2){ applyDecimalColumns(sheet, startRow, range, sheetArray[index].decimalArray2, 2); } + if(sheetArray[index].decimalArray3){ applyDecimalColumns(sheet, startRow, range, sheetArray[index].decimalArray3, 3); } + if(sheetArray[index].decimalRange0){ applyRangeFormat(sheet, sheetArray[index].decimalRange0, 0); } + if(sheetArray[index].decimalRange1){ applyRangeFormat(sheet, sheetArray[index].decimalRange1, 1); } + if(sheetArray[index].decimalRange2){ applyRangeFormat(sheet, sheetArray[index].decimalRange2, 2); } + if(sheetArray[index].decimalRange3){ applyRangeFormat(sheet, sheetArray[index].decimalRange3, 3); } + } else { + console.error(`Sheet "${sheetName}" is undefined.`); + } + } + }); + + await excelArrayStyle( + XLSX.write(wb, { bookType: "xlsx", type: "buffer" }), + sheetArray, + fileNm + ); + + return undefined; +}; + -// export const filePickedBlobArray = (oFile: ArrayBuffer, fileNm: string, sheetArray: SheetParameter[]): Promise => { -// return new Promise(async () => { -// const wb = XLSX.read(oFile, { type: 'binary' }); -// wb.SheetNames.forEach(function (sheetName, index) { -// if (sheetArray[index]) { -// const sheet = wb.Sheets[sheetName]; -// if (sheet) { -// const startCol = sheetArray[index].startCol ? sheetArray[index].startCol : 'A'; -// XLSX.utils.sheet_add_aoa(sheet, sheetArray[index].data, { origin: startCol + sheetArray[index].headerNum }); -// } else { -// console.error(`Sheet "${sheetName}" is undefined.`); -// } -// } -// }); -// await excelArrayStyle(XLSX.write(wb, { bookType: "xlsx", type: "buffer" }), sheetArray, fileNm) -// }); -// } export const filePickedBlobArray = async ( oFile: ArrayBuffer, fileNm: string, @@ -301,34 +382,10 @@ export const filePickedBlobArrayFormat = async ( XLSX.utils.sheet_add_aoa(sheet, sheetArray[index].data, { origin: startCol + sheetArray[index].headerNum, }); - const applyRangeFormat = (rangeStr: string | undefined, decimal: number) => { - if (!rangeStr) return; - const parts = rangeStr.split(",").map((part) => part.trim()).filter(Boolean); - for (const part of parts) { - const rangeInfo = XLSX.utils.decode_range(part); - 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 }); - const cell = sheet[cellAddr]; - if (cell && typeof cell.v === "number") { - if (decimal === 1) { - cell.z = "#,##0.0"; - } else if (decimal === 2) { - cell.z = "#,##0.00"; - } else if (decimal === 3) { - cell.z = "#,##0.000"; - } else { - cell.z = "#,##0"; - } - } - } - } - } - }; - applyRangeFormat(sheetArray[index].decimalRange0, 0); - applyRangeFormat(sheetArray[index].decimalRange1, 1); - applyRangeFormat(sheetArray[index].decimalRange2, 2); - applyRangeFormat(sheetArray[index].decimalRange3, 3); + applyRangeFormat(sheet, sheetArray[index].decimalRange0, 0); + applyRangeFormat(sheet, sheetArray[index].decimalRange1, 1); + applyRangeFormat(sheet, sheetArray[index].decimalRange2, 2); + applyRangeFormat(sheet, sheetArray[index].decimalRange3, 3); } else { console.error(`Sheet "${sheetName}" is undefined.`); }