diff --git a/apps/wr/app/stats/rainStat/page.tsx b/apps/wr/app/stats/rainStat/page.tsx index f9d2a1350..26faf2616 100644 --- a/apps/wr/app/stats/rainStat/page.tsx +++ b/apps/wr/app/stats/rainStat/page.tsx @@ -31,7 +31,7 @@ export default function RainStat() { searchRainStatList(searchYear); }, [code.cityCd, code.sggCd, searchRainStatList, searchYear]) - const excelDownLoad=() =>{ + const excelDetailDownLoad=() =>{ const sidoList = new Set(); const sidoDataMap = new Map(); // 시도별 데이터를 저장할 Map @@ -203,7 +203,7 @@ export default function RainStat() { - diff --git a/apps/wr/app/stats/rswtStat/page.tsx b/apps/wr/app/stats/rswtStat/page.tsx index 74a8a3c82..cd5fa667c 100644 --- a/apps/wr/app/stats/rswtStat/page.tsx +++ b/apps/wr/app/stats/rswtStat/page.tsx @@ -1,7 +1,7 @@ "use client"; import { useWrStore } from "@/app/store"; import type { ExcelType, RswtStatProps } from "@/app/store/stats/rswtStat"; -import { tableData, yearOptions } from "@/components/lib/func/commom"; +import { excelDownload, tableData, yearOptions } from "@/components/lib/func/commom"; import { ContentsDiv, SearchDiv, @@ -15,7 +15,7 @@ import { useEffect, useState } from "react"; export default function RswtStat() { const { code, rswtStat, searchRswtStatList } = useWrStore((state) => state); - const { rswtStatList, excelList } = rswtStat; + const { rswtStatList, excelList, rswtDetailList } = rswtStat; const [rswtTable, setRswtTable] = useState(); const [pageNation, setPageNation] = useState(1); const [searchYear, setSearchYear] = useState( @@ -43,6 +43,109 @@ export default function RswtStat() { const tbData = Array.isArray(excelData) }, [excelList]) + const excelDetailDownLoad=() =>{ + const sidoList = new Set(); + const sidoDataMap = new Map(); // 시도별 데이터를 저장할 Map + + console.log("rswtDetailList : ", rswtDetailList); + rswtDetailList.forEach((item: RswtStatProps[]) => { + const sidoVal = item.at(0)?.toString().trim(); + const sigunVal = item.at(1)?.toString().trim(); + + let sidoText = ''; + let sigunText = ''; + + const sido = code.cityCd.find((city) => city.val === sidoVal); + const sigun = code.sggCd.find((sgg) => sgg.val === sigunVal); + + sidoText = sido?.text || ''; + sigunText = sigun?.text || ''; + + // 시도, 시군구 코드를 텍스트로 변환하여 데이터에 할당 + if (item.length > 0) { + item[0] = sidoText as unknown as RswtStatProps; + } + if (item.length > 1) { + item[1] = sigunText as unknown as RswtStatProps; + } + if (item.length > 2) { + item[2] = sidoText+' '+sigunText as unknown as RswtStatProps; + } + + // 시도별 데이터 수집 + if (sidoText && !sidoList.has(sidoText)) { + sidoList.add(sidoText); + // 시도별 초기 데이터 구조 생성 (예: [시도명, 0, 0, 0, ...]) + const initialData: (string | number)[] = [sidoText]; + // 데이터의 나머지 컬럼들을 0으로 초기화 (실제 컬럼 수에 맞게 조정 필요) + for (let i = 1; i < item.length; i++) { + initialData.push(0); + } + sidoDataMap.set(sidoText, initialData); + } + }); + // 시도별 합계 계산 + rswtDetailList.forEach((item: RswtStatProps[]) => { + const sidoText = item[0]?.toString(); + if (sidoText && sidoDataMap.has(sidoText)) { + const sidoData = sidoDataMap.get(sidoText); + // 각 컬럼의 값을 합계에 더하기 (1번 인덱스부터 시작) + for (let i = 1; i < item.length && i < sidoData.length; i++) { + if(i == 2){ + sidoData[i] = '합계'; + } else if(i == 3){ + // 해당 시도의 데이터 개수를 계산 + const sidoDataCount = rswtDetailList.filter((data: unknown[]) => + Array.isArray(data) && data.length > 0 && String(data[0]) === sidoText + ).length; + sidoData[i] = sidoDataCount; + } else if( i == 4){ + sidoData[i] = ''; + } else if(i == 6){ + // 법정 대상 건축물 개수 (인덱스 6이 'Y'인 경우) + const bumCnt = rswtDetailList.filter((data: unknown[]) => + Array.isArray(data) && data.length > 6 && String(data[0]) === sidoText + ).filter((data: unknown[]) => String(data[6]) === 'Y').length; + sidoData[i] = bumCnt; + } else if(i==9){ + const value = Number(item[9]) || 0; + sidoData[i] = (Number(sidoData[i]) + value) as string | number; + } else if(i==10){ + const value = Number(item[10]) || 0; + sidoData[i] = (Number(sidoData[i]) + value) as string | number; + } else if(i==11){ + const value = Number(item[11]) || 0; + sidoData[i] = (Number(sidoData[i]) + value) as string | number; + } else if(i==13){ + const value = Number(item[13]) || 0; + sidoData[i] = (Number(sidoData[i]) + value) as string | number; + } else if(i==14){ + const value = Number(item[14]) || 0; + sidoData[i] = (Number(sidoData[i]) + value) as string | number; + } else if(i==16){ + const value = Number(item[16]) || 0; + sidoData[i] = (Number(sidoData[i]) + value) as string | number; + } else { + sidoData[i] = ''; + } + } + } + }); + // Map을 배열로 변환 + const sidoSummaryList = Array.from(sidoDataMap.values()); + console.log("sidoSummaryList : ", sidoSummaryList) + // sidoSummaryList와 rainDetailList를 합쳐서 엑셀 데이터 생성 + const excelData = [...sidoSummaryList, ...rswtDetailList]; + + excelDownload( + excelData, + "중수도시설 통계", + "sample_rswtStats.xlsx", + "A1:V3", + 4 + ); + } + return (<>
@@ -81,7 +184,7 @@ export default function RswtStat() { diff --git a/apps/wr/app/store/stats/rainStat/index.tsx b/apps/wr/app/store/stats/rainStat/index.tsx index 059de2b65..d6e48a53e 100644 --- a/apps/wr/app/store/stats/rainStat/index.tsx +++ b/apps/wr/app/store/stats/rainStat/index.tsx @@ -139,7 +139,7 @@ export const rainStatActionsExport = ( }) }) - //상세세 + //상세 const rainDetailList : RainStatProps[] = []; res.forEach((item:RainStatProps) => { const utztnUsgArray = new Array(); diff --git a/apps/wr/app/store/stats/rswtStat/excel.tsx b/apps/wr/app/store/stats/rswtStat/excel.tsx new file mode 100644 index 000000000..d47e0e3fe --- /dev/null +++ b/apps/wr/app/store/stats/rswtStat/excel.tsx @@ -0,0 +1,46 @@ +import type { RswtStatProps } from "."; + +export const excelRswtStat = (excelList:RswtStatProps[]) : string[][] => { + const excelData: string[][] = []; + excelList.forEach((item) => { + excelData.push([ + //시도 + String(item.ctpvCd) ?? "", + //시군구 + String(item.sggCd) ?? "", + //행정구역명 + String(item.areaNm) ?? "", + //건축물명 + String(item.bdstNm) ?? "", + //건축물용도코드(빈칸) + //String(item.bdstUsgCd) ?? "", + "", + //주소 + String(item.daddr) ?? "", + //법적의무대상여부 + String(item.lawTrgtYn) ?? "", + //설치완료일자 + String(item.instlCmptnDt) ?? "", + //가동개시일(빈칸) + //String(item.instlCst) ?? "", + "", + //건축물면적 + String(item.archArea) ?? "", + //처리용량 + String(item.filtrTrtmfctCpct) ?? "", + //물사용량 + String(item.wtrUsqty) ?? "", + //중수도+대체수이용량 + String(item.rswtAltSum) ?? "", + //중수도이용량 + String(item.rswtrUsqty) ?? "", + //대체수이용량 + String(item.altUswtrUtztnQnt) ?? "", + //중수도용도 + String(item.utztnUsgCd) ?? "", + //연간운영비 + String(item.anlOperCst) ?? "", + ]); + }); + return excelData; +} \ No newline at end of file diff --git a/apps/wr/app/store/stats/rswtStat/index.tsx b/apps/wr/app/store/stats/rswtStat/index.tsx index f1b09354e..4e2a7ecc8 100644 --- a/apps/wr/app/store/stats/rswtStat/index.tsx +++ b/apps/wr/app/store/stats/rswtStat/index.tsx @@ -1,9 +1,14 @@ import { fetchType, getFetch } from "@/components/lib/api"; import type { TableUpperProps } from "../../common/type/header"; import { rswtStatHeadListExport } from "./headList"; +import { excelRswtStat } from "./excel"; export type RswtStatProps = { ctpvCd: string //시도 + sggCd : string //시군구 + areaNm: string //행정구역명 + bdstNm: string //시설명 + daddr: string //주소 ctpvCnt: string //개소 archArea: number //건축연면적 filtrTrtmfctCpct: number //처리용량 @@ -20,6 +25,9 @@ export type RswtStatProps = { ithlEtcUswtr: number //기타 anlOperCst: number //연간운영비 guideStats: GuideStatProps[] + utztnUsgCd : string //이용코드 + lawTrgtYn : string //법적의무대상여부 + instlCmptnDt : string //설치완료일자 } export type GuideStatProps = { @@ -40,9 +48,10 @@ const excelDownList: ExcelType[] = []; export type rswtStatState = { rswtStat: { - rswtStatHeadList: TableUpperProps[] + rswtStatHeadList: TableUpperProps[]; rswtStatList: RswtStatProps[]; - excelList: ExcelType[] + excelList: ExcelType[]; + rswtDetailList: RswtStatProps[][]; } } @@ -52,7 +61,8 @@ export const rswtStatExport: rswtStatState = { rswtStat: { rswtStatHeadList: rswtStatHeadListExport, rswtStatList: [], - excelList: [] + excelList: [], + rswtDetailList: [] } } @@ -62,10 +72,9 @@ export const rswtStatActionsExport: (set: any) => rswtStatActions = ( return { searchRswtStatList: async (year: string) => { const res = await getFetch(fetchType.WR, `/reuseChk/reuseWater/stat/${year}`) - const rswtStatList: RswtStatProps[] = []; - let cityArr: any[] = []; + const cityArr: any[] = []; res.forEach((item: RswtStatProps) => { let obj = cityArr.find((e) => { return e.ctpvCd == item.ctpvCd @@ -131,11 +140,27 @@ export const rswtStatActionsExport: (set: any) => rswtStatActions = ( }) }) + //상세 + const rswtDetailList : RswtStatProps[] = []; + res.forEach((item:RswtStatProps) => { + const utztnUsgArray = new Array(); + item.guideStats.forEach((guideStat) => { + utztnUsgArray.push(guideStat.utztnUsgCd); + }) + rswtDetailList.push({ + ...item, + rswtAltSum : item.rswtrUsqty + item.altUswtrUtztnQnt, + utztnUsgCd : utztnUsgArray.join(', '), + }) + }); + + const excelDetailData = excelRswtStat(rswtDetailList); set((state: rswtStatState) => ({ rswtStat: { ...state.rswtStat, rswtStatList: cityArr, - excelList: excelDownList + excelList: excelDownList, + rswtDetailList: excelDetailData } })); } diff --git a/apps/wr/public/sample_rswtStats.xlsx b/apps/wr/public/sample_rswtStats.xlsx new file mode 100644 index 000000000..702c4cec0 Binary files /dev/null and b/apps/wr/public/sample_rswtStats.xlsx differ