팝업 엑셀 다운로드 추가

This commit is contained in:
2025-09-03 14:02:59 +09:00
parent 236cc9fdd2
commit b92baf8b2a
8 changed files with 174 additions and 22 deletions
@@ -1,10 +1,11 @@
"use client"
import CalcRainEffect from "@/app/components/common/CalcRainEffect";
import { roundNumber } from "@/app/components/common/DataForm";
import { useFoStore } from "@/app/store";
import type { PrecipitationPropsDetailProps } from "@/app/store/facilityPrecipitation";
import { DatePickerRange, UiTable } from "@common/business_components/ui";
import { DatePickerRange, downloadExcel, UiTable } from "@common/business_components/ui";
import ListDiv from "@common/business_components/ui/list_div";
import { Table, TableCell, TableHead, TableRow } from "@common/components/ui";
import { Button, Table, TableCell, TableHead, TableRow } from "@common/components/ui";
import { useEffect, useRef, useState } from "react";
type PrecipitationModalProps = {
@@ -20,9 +21,9 @@ type DateRange = {
}
export default function PrecipitationModal(props: PrecipitationModalProps) {
const { PrecipitationDetail } = useFoStore((state) => state);
const { Common, PrecipitationDetail } = useFoStore((state) => state);
const { upHeadListPrecipitationDetail } = PrecipitationDetail;
const { btnClass } = Common;
// Refs
const startPickerRef = useRef<HTMLDivElement>(null);
const endPickerRef = useRef<HTMLDivElement>(null);
@@ -146,6 +147,26 @@ export default function PrecipitationModal(props: PrecipitationModalProps) {
}
}, [props.detailList, props.facilityCd]);
const excelDownload = () => {
const totData = getTableData();
const excelDownList: any[] = [];
if(totData.length > 0){
totData.forEach((item) => {
excelDownList.push({
"날짜": item.rainDt,
"강수량(mm/일)": roundNumber(item.infoRnDay, 1),
"강우일(일)": roundNumber(item.rainDay, 0),
"강우영향일(일)": roundNumber(item.rainEffectDay, 0),
});
});
}
if (excelDownList && excelDownList.length > 0) {
downloadExcel({ data: JSON.parse(JSON.stringify(excelDownList)), fileName: props.searchYear+'년 '+props.fcltyName + ' 강수현황', sheetNameArray: ['지하수유입량'], headerRange: 'A1:D1' });
} else if (totData.length == 0) {
alert('다운받을 데이터가 없습니다.');
}
}
return (
<>
<ListDiv className="!mt-5 !h-[80px]">
@@ -187,6 +208,9 @@ export default function PrecipitationModal(props: PrecipitationModalProps) {
</div>
</ListDiv>
<ListDiv className="h-[550px] overflow-y-auto">
<Button className={btnClass} style={{float: 'right'}} color="green" onClick={excelDownload}>
{"엑셀다운로드"}
</Button>
<UiTable
headName={"강수현황"}
tableData={getTableData()}
@@ -1,12 +1,13 @@
"use client"
import { roundNumber } from "@/app/components/common/DataForm";
import { useFoStore } from "@/app/store";
import type { TableUpperProps } from "@/app/store/dashboard";
import { UITab, UiTable } from "@common/business_components/ui";
import { downloadExcel, filePickedBlobArray, UITab, UiTable } from "@common/business_components/ui";
import ListDiv from "@common/business_components/ui/list_div";
import {
TabsContent
} from "@common/components";
import { Table, TableCell, TableHead, TableRow } from "@common/components/ui";
import { Button, Table, TableCell, TableHead, TableRow } from "@common/components/ui";
type ModalType = {
fcltyName: string;
@@ -82,8 +83,8 @@ const headMakeList = (upHeadList: TableUpperProps[], gridNum:number) => {
export default function ProcessFacilityInfoModal(props: ModalType) {
// 그리드 관련
const {ProcessFacilityDetail} = useFoStore((state) => state);
const {Common, ProcessFacilityDetail} = useFoStore((state) => state);
const { btnClass } = Common;
const {
upHeadListPlanInfo,
gridListPlanInfo,
@@ -115,6 +116,79 @@ export default function ProcessFacilityInfoModal(props: ModalType) {
const upHeadListPlanInfoChange = headMakeList(upHeadListPlanInfo, 2);
const upHeadListFcltyHistInfoChange = headMakeList(upHeadListFcltyHistInfo, 3);
const upHeadListFcltyWaterQltyInfoChange = headMakeList(upHeadListFcltyWaterQltyInfo, 4);
const excelDownloadPlan = () => {
const excelDownList: any[] = [];
console.log('gridListFcltyHistInfo : ' , gridListFcltyHistInfo)
if(gridListFcltyHistInfo.length > 0){
gridListFcltyHistInfo.forEach((item) => {
excelDownList.push({
"차수": item.extnsSeqno,
"구분": item.extnsNm,
"사업시작일": item.bzStrtYrMnth,
"사업종료일": item.bzEdYrMnth,
"설치인가일": item.eqpPrmsDt,
"준공일": item.cmplDt,
"시운전완료일": item.trlrnCmplDt,
"가동개시일": item.rnDt,
"시설용량(m³/일)": roundNumber(item.fctCpc,0),
});
});
}
if (excelDownList && excelDownList.length > 0) {
downloadExcel({ data: JSON.parse(JSON.stringify(excelDownList)), fileName: props.fcltyName + ' 시설이력관리', sheetNameArray: [props.fcltyName + ' 시설이력관리'], headerRange: 'A1:I1' });
} else if (gridListFcltyHistInfo.length == 0) {
alert('다운받을 데이터가 없습니다.');
}
}
const excelDownloadQlty = () => {
fetch(`/dashBoadModalWaterQlty.xlsx`, {}).then(async (response) => {
if (!response.ok) {
throw Error(response.statusText);
}
// 받은 파일 바인너리 처리
const blobRet = await response.arrayBuffer();
const excelData = gridListFcltyWaterQltyInfo.map((item) => {
return [
item.extnsSeqno,
item.plInflWqltBod,
item.plInflWqltToc,
item.plInflWqltCod,
item.plInflWqltSs,
item.plInflWqltTn,
item.plInflWqltTp,
item.dsInflWqltBod,
item.dsInflWqltToc,
item.dsInflWqltCod,
item.dsInflWqltSs,
item.dsInflWqltTn,
item.dsInflWqltTp,
item.plEfflWqltBod,
item.plEfflWqltToc,
item.plEfflWqltCod,
item.plEfflWqltSs,
item.plEfflWqltTn,
item.plEfflWqltTp,
];
});
const sheetParameter = [
{
data: excelData,
headerNum: 2,
headerRange: 'A1:S2',
sheetName: '시설 수질정보',
startCol: 'A'
},
];
// 버퍼에 있는 엑셀데이터 전달 후 json으로 변환
await filePickedBlobArray(blobRet, props.fcltyName +' 수질정보', sheetParameter);
});
}
return (
<>
<ListDiv className="!h-[80px]">
@@ -185,6 +259,9 @@ export default function ProcessFacilityInfoModal(props: ModalType) {
<TabsContent value="history_info">
<ListDiv>
<div className="h-[250px] w-full overflow-y-auto overflow-x-hidden">
<Button className={btnClass} style={{float: 'right'}} color="green" onClick={excelDownloadPlan}>
{"엑셀다운로드"}
</Button>
<div className="h-[120%]">
<UiTable headName={"시설 이력관리"} tableData={gridListFcltyHistInfo} headlist={upHeadListFcltyHistInfo} pageSize={0} total={0} cellClick={undefined} onPageChange={()=>{}}>
{upHeadListFcltyHistInfoChange}
@@ -194,6 +271,9 @@ export default function ProcessFacilityInfoModal(props: ModalType) {
</ListDiv>
<ListDiv>
<div className="h-[250px] w-full overflow-y-auto overflow-x-hidden">
<Button className={btnClass} style={{float: 'right'}} color="green" onClick={excelDownloadQlty}>
{"엑셀다운로드"}
</Button>
<div className="h-[120%]">
<UiTable headName={"시설 수질정보"} tableData={gridListFcltyWaterQltyInfo} headlist={upHeadListFcltyWaterQltyInfo} pageSize={0} total={0} cellClick={undefined} onPageChange={()=>{}}>
{upHeadListFcltyWaterQltyInfoChange}
@@ -1,15 +1,17 @@
"use client"
import { roundNumber } from "@/app/components/common/DataForm";
import { useFoStore } from "@/app/store";
import type { modalTableType } from "@/app/store/sewageOccur";
import { DateMonthPicker, UiTable } from "@common/business_components/ui";
import { DateMonthPicker, downloadExcel, UiTable } from "@common/business_components/ui";
import ListDiv from "@common/business_components/ui/list_div";
import { Table, TableCell, TableHead, TableRow } from "@common/components/ui";
import { Button, Table, TableCell, TableHead, TableRow } from "@common/components/ui";
import { useEffect, useState } from "react";
export default function SewageOccurModal(props: { fcltyName: string; facilityCd : string; searchYear : string}) {
// 그리드 관련
const {SewageOccurDetail, searchSewageOccurDetailList} = useFoStore((state) => state);
const { Common, SewageOccurDetail, searchSewageOccurDetailList} = useFoStore((state) => state);
const { btnClass } = Common;
// searchYear 유효성 검사 및 기본값 설정
const validSearchYear = props.searchYear && /^\d{4}$/.test(props.searchYear) ? props.searchYear : new Date().getFullYear().toString();
@@ -61,6 +63,25 @@ export default function SewageOccurModal(props: { fcltyName: string; facilityCd
}
}, [endYearMonth, startYearMonth]);
const excelDownload = () => {
const excelDownList: any[] = [];
if(detailList.length > 0){
detailList.forEach((item) => {
excelDownList.push({
"날짜": item.msrDt,
"물사용량(m³/일)": roundNumber(item.waterUsage, 0),
"오수전환율(%)": roundNumber(item.swageChangePercent, 0),
"오수발생량 추정(m³/일)": roundNumber(item.estimationSewage, 0),
});
});
}
if (excelDownList && excelDownList.length > 0) {
downloadExcel({ data: JSON.parse(JSON.stringify(excelDownList)), fileName: props.searchYear+'년 '+props.fcltyName + ' 오수발생량 추정', sheetNameArray: [props.fcltyName + ' 오수발생량 추정'], headerRange: 'A1:D1' });
} else if (detailList.length == 0) {
alert('다운받을 데이터가 없습니다.');
}
}
return (
<>
<ListDiv className="!h-[80px] !mt-10">
@@ -118,6 +139,9 @@ export default function SewageOccurModal(props: { fcltyName: string; facilityCd
</ListDiv>
<ListDiv className="!h-[570px] overflow-y-auto">
<div className="h-[120%]">
<Button className={btnClass} style={{float: 'right'}} color="green" onClick={excelDownload}>
{"엑셀다운로드"}
</Button>
<UiTable headName={"오수발생량 추정"} tableData={detailList} headlist={upHeadListSewageOccurDetail} pageSize={0} total={0} cellClick={undefined} onPageChange={() => {}} boldArray={[0, 1, 2]}>
</UiTable>
</div>
@@ -1,9 +1,11 @@
"use client"
import { roundNumber } from "@/app/components/common/DataForm";
import { useFoStore } from "@/app/store";
import type { UnderWaterInputModalProps } from "@/app/store/underWaterInput/types";
import { downloadExcel } from "@common/business_components";
import { DateMonthPicker, UITab, UiTable } from "@common/business_components/ui";
import ListDiv from "@common/business_components/ui/list_div";
import { Table, TableCell, TableHead, TableRow, TabsContent } from "@common/components/ui";
import { Button, Table, TableCell, TableHead, TableRow, TabsContent } from "@common/components/ui";
import { useEffect, useState } from "react";
type ModalProps ={
@@ -20,8 +22,8 @@ const tabList1 = [
export default function UnderWaterInputModal({fcltyCd='', fcltyName='',searchYear=new Date().getFullYear().toString()} : ModalProps) {
// 그리드 관련
const {UnderWaterDetail, unserWaterModal} = useFoStore((state) => state);
const {Common, UnderWaterDetail, unserWaterModal} = useFoStore((state) => state);
const { btnClass } = Common;
const [startYmDate, setStartYmDate] = useState<string>(searchYear+'01');
const [endYmDate, setEndYmDate] = useState<string>(searchYear+'12');
const [tabTerm, setTabTerm] = useState<string>('tab_term_year');
@@ -87,9 +89,31 @@ export default function UnderWaterInputModal({fcltyCd='', fcltyName='',searchYea
unserWaterModal(fcltyCd, searchYear, prevStartYmDate, prevEndYmDate);
} , [fcltyCd, searchYear, unserWaterModal, prevStartYmDate, prevEndYmDate]);
const excelDownload = () => {
const excelDownList: any[] = [];
if(copyYearList.length > 0){
copyYearList.forEach((item) => {
excelDownList.push({
"날짜": item.msrDt,
"청천시 실제 하수유입량(m³/일)": roundNumber(item.realSewageInput, 0),
"오수발생량(m³/일)": roundNumber(item.sewageOccur, 0),
"지하수 유입량(m³/일)": roundNumber(item.underWaterInput, 0),
});
});
}
if (excelDownList && excelDownList.length > 0) {
downloadExcel({ data: JSON.parse(JSON.stringify(excelDownList)), fileName: searchYear+'년 '+fcltyName + ' 지하수유입량', sheetNameArray: [fcltyName + ' 지하수유입량'], headerRange: 'A1:D1' });
} else if (copyYearList.length == 0) {
alert('다운받을 데이터가 없습니다.');
}
}
return (
<>
<UITab tabList={tabList1} defaultValue="tab_term_year" onValueChange={(val) => {setTabTerm(val)}}>
<Button className={btnClass} style={{float: 'right'}} color="green" onClick={excelDownload}>
{"엑셀다운로드"}
</Button>
<TabsContent value="tab_term_year">
<ListDiv className="!h-[100px]">
<div className="card !m-[1.2rem] max-h-[40rem] overflow-auto !p-0r">
+1 -1
View File
@@ -420,7 +420,7 @@ export const commonState: CommonType = {
selectFlowTerm: selectFlowTerm,
selectFlowPanel: selectFlowPanel,
selectEnvPartData: selectEnvPartData,
btnClass: "p-4 m-2 text-white rounded-sm text-lg font-medium",
btnClass: "p-4 m-2 !mr-10 text-white rounded-sm text-lg font-medium",
},
auth: {
+2 -2
View File
@@ -118,7 +118,7 @@ export type fcltyHistInfoProps = {
sitArea : number,
trtDstrArea : number,
swrTrtPopl : number,
fcltCpc : number | ''
fctCpc : number | ''
}
// 시설 수질정보
@@ -345,7 +345,7 @@ const gridListFcltyHistInfo:fcltyHistInfoProps[] = [
sitArea : 0,
trtDstrArea : 0,
swrTrtPopl : 0,
fcltCpc : 860000
fctCpc : 860000
}
];
+4 -4
View File
@@ -307,16 +307,16 @@ export const underWaterReducer:(set:(fn: (state: UnderWaterType) => UnderWaterTy
sumWinterChungcunFlow += flowItem.inflAmnt && flowItem.inflAmnt !== 'x' ? Number(flowItem.inflAmnt.toString().trim()) : 0;
}
});
const usage = chungcunSumFlow / calData.length;
const summerUsage = sumSummerChungcunFlow / sumSummerChungcunDay;
const winterUsage = sumWinterChungcunFlow / sumWinterChungcunDay;
const usage = chungcunSumFlow&&chungcunSumFlow>0?chungcunSumFlow / calData.length:0;
const summerUsage = sumSummerChungcunFlow?sumSummerChungcunFlow / sumSummerChungcunDay:0;
const winterUsage = sumWinterChungcunFlow?sumWinterChungcunFlow / sumWinterChungcunDay:0;
//bscFctCd === '11200PB001R') 중랑 - 테스트할 때 코드넣고 해야 보기편해요~
/* if(bscFctCd === '11200PB001R') {
console.log('calData.length : ', calData.length);
console.log('usage : ', usage, 'summerUsage : ', summerUsage, 'winterUsage : ', winterUsage);
} */
console.log(item.bscFctCd+'. '+' '+sumSummerChungcunFlow+' '+sumSummerChungcunDay+' '+summerUsage);
item.underWaterInputYear = Math.round((usage-(usage*0.65*OSU_PERCENT)) * 1) / 1;
item.underWaterInputSummer = Math.round((summerUsage-(summerUsage*0.65*OSU_PERCENT)) * 1) / 1;
item.underWaterInputWinter = Math.round((winterUsage-(winterUsage*0.65*OSU_PERCENT)) * 1) / 1;
Binary file not shown.