From 3787f824df88b6b879e18c7d36a1830c1d7a2eea Mon Sep 17 00:00:00 2001 From: dongsilove Date: Mon, 9 Feb 2026 22:38:10 +0900 Subject: [PATCH] =?UTF-8?q?fo:=20exceldown=EC=8B=9C=20,=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../facilityPrecipitation/page.tsx | 7 ++-- .../(with-layout)/facilityWaterQlty/page.tsx | 3 +- .../pages/(with-layout)/planSewage/page.tsx | 32 ++++++++++++++--- .../pages/(with-layout)/processArea/page.tsx | 11 ++++-- .../(with-layout)/processFacility/page.tsx | 10 ++++-- apps/fo/app/pages/(with-layout)/rdi/page.tsx | 36 ++++++++++++++++--- .../pages/(with-layout)/sewageOccur/page.tsx | 34 +++++++++++++++--- .../(with-layout)/underWaterInput/page.tsx | 33 ++++++++++++++--- 8 files changed, 140 insertions(+), 26 deletions(-) diff --git a/apps/fo/app/pages/(with-layout)/facilityPrecipitation/page.tsx b/apps/fo/app/pages/(with-layout)/facilityPrecipitation/page.tsx index 7fd141694..9570320d4 100644 --- a/apps/fo/app/pages/(with-layout)/facilityPrecipitation/page.tsx +++ b/apps/fo/app/pages/(with-layout)/facilityPrecipitation/page.tsx @@ -7,7 +7,7 @@ "use client" import { StoreContext, useFoStore } from "@/app/store"; import type { TableUpperProps } from "@/app/store/common"; -import { ContentsDiv, downloadExcel, MainDiv, SearchBaseForm, SearchInput, SelectBox, Title, UiModal, UiTable, type ReturnType } from "@common/business_components"; +import { ContentsDiv, downloadExcelFormat, MainDiv, SearchBaseForm, SearchInput, SelectBox, Title, UiModal, UiTable, type ReturnType } from "@common/business_components"; import ListDiv from "@common/business_components/ui/list_div"; import { useCallback, useContext, useEffect, useRef, useState } from "react"; import PrecipitationModal from "./modal/page"; @@ -212,11 +212,12 @@ export default function FacilityPrecipitation() { await searchFacilityPrecipitation(searchReturn, 1, 10000); const latestExcelList = store.getState().FacilityPrecipitation.excelList || []; if (latestExcelList.length > 0) { - downloadExcel({ + downloadExcelFormat({ data: latestExcelList as unknown as JSON[], fileName: '시설별 강수현황', sheetNameArray: ['시설별 강수현황'], - headerRange: 'A1:N1' + headerRange: 'A1:N1', + decimalArray0: [9, 11, 12, 13], }); } else { alert("조회된 결과가 없습니다."); diff --git a/apps/fo/app/pages/(with-layout)/facilityWaterQlty/page.tsx b/apps/fo/app/pages/(with-layout)/facilityWaterQlty/page.tsx index 265c9788f..a90929225 100644 --- a/apps/fo/app/pages/(with-layout)/facilityWaterQlty/page.tsx +++ b/apps/fo/app/pages/(with-layout)/facilityWaterQlty/page.tsx @@ -191,8 +191,7 @@ export default function ProcessFacilitySearch() { fileName: '시설별 수질현황', sheetNameArray: ['시설별 수질현황'], headerRange: 'A1:T1', - decimalArray1: [10, 11, 12, 15, 16, 17], - decimalArray3: [13, 14, 18, 19] + decimalArray0: [9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19] } ); } else { diff --git a/apps/fo/app/pages/(with-layout)/planSewage/page.tsx b/apps/fo/app/pages/(with-layout)/planSewage/page.tsx index 8b41524d1..bdfd9c4b4 100644 --- a/apps/fo/app/pages/(with-layout)/planSewage/page.tsx +++ b/apps/fo/app/pages/(with-layout)/planSewage/page.tsx @@ -7,7 +7,7 @@ "use client" import { StoreContext, useFoStore } from "@/app/store"; import type { TableUpperProps } from "@/app/store/common"; -import { downloadExcel, MainDiv, SearchBaseForm, SearchInput, SelectBox, Title, UiTable, type ReturnType } from "@common/business_components"; +import { downloadExcelFormat, MainDiv, SearchBaseForm, SearchInput, SelectBox, Title, UiTable, type ReturnType } from "@common/business_components"; import ListDiv from "@common/business_components/ui/list_div"; import { useCallback, useContext, useEffect, useRef, useState } from "react"; import LoadingOverlay from "@common/business_components/ui/loadingBar"; @@ -197,11 +197,35 @@ export default function PlanSewage() { await searchPlanSewage(searchReturn, 1, 10000); const latestExcelList = store.getState().PlanSewage.excelList || []; if (latestExcelList.length > 0) { - downloadExcel({ - data: latestExcelList as unknown as JSON[], + const toNumber = (value: unknown) => { + if (value === null || value === undefined || value === '') return ''; + const parsed = typeof value === "number" ? value : Number(String(value).replace(/,/g, "")); + return Number.isFinite(parsed) ? parsed : ''; + }; + + const numericKeys = [ + "시설용량(m³/일)", + "여유용량(m³/일)", + "변동부하율(%)", + "분류식화율(%)", + ]; + + const excelData = latestExcelList.map((row) => { + const nextRow = { ...row } as Record; + numericKeys.forEach((key) => { + if (key in nextRow) { + nextRow[key] = toNumber(nextRow[key]); + } + }); + return nextRow; + }); + + downloadExcelFormat({ + data: excelData as unknown as JSON[], fileName: '계획하수량 산정지표 현황', sheetNameArray: ['계획하수량 산정지표 현황'], - headerRange: 'A1:M1' + headerRange: 'A1:M1', + decimalArray0: [9, 10, 11, 12] }); } else { alert("조회된 결과가 없습니다."); diff --git a/apps/fo/app/pages/(with-layout)/processArea/page.tsx b/apps/fo/app/pages/(with-layout)/processArea/page.tsx index 84d8ee8b1..60dfff2cc 100644 --- a/apps/fo/app/pages/(with-layout)/processArea/page.tsx +++ b/apps/fo/app/pages/(with-layout)/processArea/page.tsx @@ -7,7 +7,7 @@ "use client" import { StoreContext, useFoStore } from "@/app/store"; import { useShallow } from 'zustand/react/shallow'; -import { ContentsDiv, downloadExcel, MainDiv, SearchBaseForm, SelectBox, Title, UiModal, UiTable, type ReturnType } from "@common/business_components"; +import { ContentsDiv, downloadExcelFormat, MainDiv, SearchBaseForm, SelectBox, Title, UiModal, UiTable, type ReturnType } from "@common/business_components"; import ListDiv from "@common/business_components/ui/list_div"; import { useCallback, useContext, useEffect, useRef, useState } from "react"; import ProcessFacilityInfoModal from "./modal/page"; @@ -155,11 +155,16 @@ export default function ProcessArea() { await searchProcessArea(ref.current, 1, 10000); const latestExcelList = store.getState().ProcessArea.excelList || []; if (latestExcelList.length > 0) { - downloadExcel({ + downloadExcelFormat({ data: latestExcelList as unknown as JSON[], fileName: '처리구역정보', sheetNameArray: ['처리구역정보'], - headerRange: 'A1:W1' + headerRange: 'A1:W1', + decimalArray0: [ + 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, + 17, 18, 19, 20, 21 + ] }); } else { alert('조회된 결과가 없습니다.'); diff --git a/apps/fo/app/pages/(with-layout)/processFacility/page.tsx b/apps/fo/app/pages/(with-layout)/processFacility/page.tsx index e73213bb1..76546b4d7 100644 --- a/apps/fo/app/pages/(with-layout)/processFacility/page.tsx +++ b/apps/fo/app/pages/(with-layout)/processFacility/page.tsx @@ -7,7 +7,7 @@ "use client" import UnderComment from "@/app/components/common/UnderComment"; import { StoreContext, useFoStore } from "@/app/store"; -import { ContentsDiv, downloadExcel, MainDiv, SearchBaseForm, SearchInput, SelectBox, Title, UiModal, UiTable, type ReturnType } from "@common/business_components"; +import { ContentsDiv, downloadExcelFormat, MainDiv, SearchBaseForm, SearchInput, SelectBox, Title, 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"; @@ -258,7 +258,13 @@ export default function ProcessFacilitySearch() { await searchFcltyList(ref.current, 1, 10000); const latestExcelList = store.getState().ProcessFacilityList.excelList || []; if (latestExcelList.length > 0) { - downloadExcel({ data: latestExcelList as unknown as JSON[], fileName: '처리시설 시설정보', sheetNameArray: ['처리시설 시설정보'], headerRange: 'A1:P1' }); + downloadExcelFormat({ + data: latestExcelList as unknown as JSON[], + fileName: '처리시설 시설정보', + sheetNameArray: ['처리시설 시설정보'], + headerRange: 'A1:P1', + decimalArray0: [9, 10, 11], + }); } else { alert('조회된 결과가 없습니다.'); } diff --git a/apps/fo/app/pages/(with-layout)/rdi/page.tsx b/apps/fo/app/pages/(with-layout)/rdi/page.tsx index 459cd44ca..ff4b8d205 100644 --- a/apps/fo/app/pages/(with-layout)/rdi/page.tsx +++ b/apps/fo/app/pages/(with-layout)/rdi/page.tsx @@ -7,7 +7,7 @@ "use client" import { StoreContext, useFoStore } from "@/app/store"; import type { TableUpperProps } from "@/app/store/common"; -import { ContentsDiv, downloadExcel, MainDiv, SearchBaseForm, SearchInput, SelectBox, Title, UiTable, type ReturnType } from "@common/business_components"; +import { ContentsDiv, downloadExcelFormat, MainDiv, SearchBaseForm, SearchInput, SelectBox, Title, UiTable, type ReturnType } from "@common/business_components"; import ListDiv from "@common/business_components/ui/list_div"; import { useCallback, useContext, useEffect, useRef, useState } from "react"; import LoadingOverlay from "@common/business_components/ui/loadingBar"; @@ -195,11 +195,39 @@ export default function Rdi() { await searchRdi(ref.current, 1, 5000); const latestExcelList = store.getState().Rdi.excelList || []; if (latestExcelList.length > 0) { - downloadExcel({ - data: latestExcelList as unknown as JSON[], + const toNumber = (value: unknown) => { + if (value === null || value === undefined || value === '') return ''; + const parsed = typeof value === "number" ? value : Number(String(value).replace(/,/g, "")); + return Number.isFinite(parsed) ? parsed : ''; + }; + + const numericKeys = [ + "시설용량(m³/일)", + "청천시유입하수량(m³/일)", + "하절기강우일최저유입BOD(mg/L)", + "하절기최저유입BOD유입유량(m³/일)", + "동절기청천시유입BOD(mg/L)", + "RDII추정", + "RDII추정시일강수량(mm)", + "강우시총추정유입량(m³/일)", + ]; + + const excelData = latestExcelList.map((row) => { + const nextRow = { ...row } as Record; + numericKeys.forEach((key) => { + if (key in nextRow) { + nextRow[key] = toNumber(nextRow[key]); + } + }); + return nextRow; + }); + + downloadExcelFormat({ + data: excelData as unknown as JSON[], fileName: 'RDII추정', sheetNameArray: ['RDII추정'], - headerRange: 'A1:R1' + headerRange: 'A1:R1', + decimalArray0: [9, 10, 11, 12, 13, 14, 15, 16], }); } else { alert("조회된 결과가 없습니다."); diff --git a/apps/fo/app/pages/(with-layout)/sewageOccur/page.tsx b/apps/fo/app/pages/(with-layout)/sewageOccur/page.tsx index 4dc3125d1..95aa8961a 100644 --- a/apps/fo/app/pages/(with-layout)/sewageOccur/page.tsx +++ b/apps/fo/app/pages/(with-layout)/sewageOccur/page.tsx @@ -9,7 +9,7 @@ import { StoreContext, useFoStore } from "@/app/store"; import { type TableUpperProps } from "@/app/store/common"; import type { SewageOccurProps } from "@/app/store/sewageOccur"; -import { ContentsDiv, downloadExcel, MainDiv, SearchBaseForm, SearchInput, SelectBox, Title, UiModal, UiTable, type ReturnType } from "@common/business_components"; +import { ContentsDiv, downloadExcelFormat, MainDiv, SearchBaseForm, SearchInput, SelectBox, Title, 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"; @@ -210,11 +210,37 @@ export default function PlanSewage() { await searchFacilityPrecipitation(ref.current, 1, 5000); const latestExcelList = store.getState().SewageOccur.excelList || []; if (latestExcelList.length > 0) { - downloadExcel({ - data: latestExcelList as unknown as JSON[], + const toNumber = (value: unknown) => { + if (value === null || value === undefined || value === '') return ''; + const parsed = typeof value === "number" ? value : Number(String(value).replace(/,/g, "")); + return Number.isFinite(parsed) ? parsed : ''; + }; + + const numericKeys = [ + "시설용량(m³/일)", + "물사용량(m³/일)", + "오수전환율(%)", + "오수발생량추정(m³/일)", + "연간하수유입량(m³/일)", + "청천시하수유입량(m³/일)", + ]; + + const excelData = latestExcelList.map((row) => { + const nextRow = { ...row } as Record; + numericKeys.forEach((key) => { + if (key in nextRow) { + nextRow[key] = toNumber(nextRow[key]); + } + }); + return nextRow; + }); + + downloadExcelFormat({ + data: excelData as unknown as JSON[], fileName: '오수발생량 추정', sheetNameArray: ['오수발생량 추정'], - headerRange: 'A1:O1' + headerRange: 'A1:O1', + decimalArray0: [9, 10, 11, 12, 13, 14] }); } else { alert("조회된 결과가 없습니다."); diff --git a/apps/fo/app/pages/(with-layout)/underWaterInput/page.tsx b/apps/fo/app/pages/(with-layout)/underWaterInput/page.tsx index 4404403e3..36fbff308 100644 --- a/apps/fo/app/pages/(with-layout)/underWaterInput/page.tsx +++ b/apps/fo/app/pages/(with-layout)/underWaterInput/page.tsx @@ -9,7 +9,7 @@ "use client" import { StoreContext, useFoStore } from "@/app/store"; import type { TableUpperProps } from "@/app/store/common"; -import { ContentsDiv, downloadExcel, MainDiv, SearchBaseForm, SearchInput, SelectBox, Title, UiModal, UiTable, type ReturnType } from "@common/business_components"; +import { ContentsDiv, downloadExcelFormat, MainDiv, SearchBaseForm, SearchInput, SelectBox, Title, UiModal, UiTable, type ReturnType } from "@common/business_components"; import ListDiv from "@common/business_components/ui/list_div"; import { useCallback, useContext, useEffect, useRef, useState } from "react"; import UnderWaterInputModal from "./modal/page"; @@ -216,11 +216,36 @@ export default function UnderWaterInput() { await searchFacilityPrecipitation(ref.current, 1, 5000); const latestExcelList = store.getState().UnderWater.excelList || []; if (latestExcelList.length > 0) { - downloadExcel({ - data: latestExcelList as unknown as JSON[], + const toNumber = (value: unknown) => { + if (value === null || value === undefined || value === '') return ''; + const parsed = typeof value === "number" ? value : Number(String(value).replace(/,/g, "")); + return Number.isFinite(parsed) ? parsed : ''; + }; + + const numericKeys = [ + "시설용량(m³/일)", + "평균유입하수량(m³/일)", + "연간지하수유입량(m³/일)", + "하절기지하수유입량(m³/일)", + "동절기지하수유입량(m³/일)", + ]; + + const excelData = latestExcelList.map((row) => { + const nextRow = { ...row } as Record; + numericKeys.forEach((key) => { + if (key in nextRow) { + nextRow[key] = toNumber(nextRow[key]); + } + }); + return nextRow; + }); + + downloadExcelFormat({ + data: excelData as unknown as JSON[], fileName: '지하수유입량 추정', sheetNameArray: ['지하수유입량 추정'], - headerRange: 'A1:O1' + headerRange: 'A1:O1', + decimalArray0: [9, 10, 11, 12, 13] }); } else { alert("조회된 결과가 없습니다.");