엑셀 시도별로 소계 추가

This commit is contained in:
YangJinSoo94
2025-06-20 11:03:38 +09:00
parent 8cccf62a91
commit 10ebd8cbef
2 changed files with 80 additions and 26 deletions
+39 -12
View File
@@ -19,9 +19,8 @@ import { useEffect, useState } from "react";
export default function RainStat() {
const { code, rainStat, searchRainStatList } = useWrStore((state) => state);
const { rainStatHeadList, rainStatList, excelList, rainDetailList } = rainStat;
const { rainStatList, excelList, rainDetailList } = rainStat;
const [pageNation, setPageNation] = useState(1);
const [searchYear, setSearchYear] = useState<string>(
String(new Date().getFullYear())
);
@@ -33,9 +32,11 @@ export default function RainStat() {
}, [code.cityCd, code.sggCd, searchRainStatList, searchYear])
const excelDetailDownLoad=() =>{
const sidoList = new Set();
const sidoDataMap = new Map(); // 시도별 데이터를 저장할 Map
const sidoList = new Set<string>();
const sidoDataMap = new Map<string, (string | number)[]>(); // 시도별 데이터를 저장할 Map
const sidoDetailMap = new Map<string, (string | number)[][]>(); // 시도별 상세 데이터를 저장할 Map
// 먼저 시도별 상세 데이터를 그룹화
rainDetailList.forEach((item: RainStatProps[]) => {
const sidoVal = item.at(0)?.toString().trim();
const sigunVal = item.at(1)?.toString().trim();
@@ -60,7 +61,15 @@ export default function RainStat() {
item[2] = sidoText+' '+sigunText as unknown as RainStatProps;
}
// 시도별 데이터 수집
// 시도별 상세 데이터 수집
if (sidoText) {
if (!sidoDetailMap.has(sidoText)) {
sidoDetailMap.set(sidoText, []);
}
sidoDetailMap.get(sidoText)!.push(item as unknown as (string | number)[]);
}
// 시도별 합계 데이터 수집
if (sidoText && !sidoList.has(sidoText)) {
sidoList.add(sidoText);
// 시도별 초기 데이터 구조 생성 (예: [시도명, 0, 0, 0, ...])
@@ -72,11 +81,12 @@ export default function RainStat() {
sidoDataMap.set(sidoText, initialData);
}
});
// 시도별 합계 계산
rainDetailList.forEach((item: RainStatProps[]) => {
const sidoText = item[0]?.toString();
if (sidoText && sidoDataMap.has(sidoText)) {
const sidoData = sidoDataMap.get(sidoText);
const sidoData = sidoDataMap.get(sidoText)!;
// 각 컬럼의 값을 합계에 더하기 (1번 인덱스부터 시작)
for (let i = 1; i < item.length && i < sidoData.length; i++) {
if(i == 2){
@@ -115,13 +125,30 @@ export default function RainStat() {
}
});
// Map을 배열로 변환
// 시도별로 합계와 상세 데이터를 순서대로 배치
const summaryExcelData: (string | number)[][] = [];
// 시도별로 순회하면서 합계와 상세 데이터를 추가
Array.from(sidoList).forEach((sidoText) => {
const sidoSummary = sidoDataMap.get(sidoText);
const sidoDetails = sidoDetailMap.get(sidoText) || [];
if (sidoSummary) {
// 시도 합계 데이터 추가
summaryExcelData.push(sidoSummary);
// 해당 시도의 상세 데이터들 추가
sidoDetails.forEach(detail => {
summaryExcelData.push(detail);
});
}
});
const sidoSummaryList = Array.from(sidoDataMap.values());
// sidoSummaryList와 rainDetailList를 합쳐서 엑셀 데이터 생성
const excelData = [...sidoSummaryList, ...rainDetailList];
const excelData = [...sidoSummaryList, ...summaryExcelData];
excelDownload(
excelData,
excelData as unknown as [][],
"빗물이용시설 통계",
"sample_rainStats.xlsx",
"A1:V3",
@@ -144,7 +171,7 @@ export default function RainStat() {
const tbData = Array.isArray(excelData)
? excelData.map((item: RainStatProps) => {
return {
"시도": item.cityText,
"시도": item.ctpvCd,
"개소": item.tmp,
"설치비(백만원)": item.instlCst,
"저류조용량(m³/년)": item.dtfcltCpct,
@@ -170,7 +197,7 @@ export default function RainStat() {
? data.map((item: RainStatProps) => {
return {
...item,
ctpvCd: item.cityText
ctpvCd: item.ctpvCd
};
})
: [];
@@ -198,7 +225,7 @@ export default function RainStat() {
/>
</div>
<div className="flex flex-row space-x-2 items-center">
<Button className="" size={"sm"} onClick={(e) => { }}>
<Button className="" size={"sm"} onClick={() => { }}>
조회
</Button>
<Button className="" size={"sm"} onClick={() => excelClick()}>
+41 -14
View File
@@ -19,11 +19,10 @@ export default function RswtStat() {
const { code, rswtStat, searchRswtStatList } = useWrStore((state) => state);
const { rswtStatList, excelList, rswtDetailList } = rswtStat;
const [rswtTable, setRswtTable] = useState<RswtStatProps[]>();
const [pageNation, setPageNation] = useState(1);
const [searchYear, setSearchYear] = useState<string>(
String(new Date().getFullYear())
);
const [excelData, setExceData] = useState<any[]>();
const [excelData, setExceData] = useState<Record<string, string | number>[]>();
useEffect(() => {
searchRswtStatList(searchYear)
@@ -45,12 +44,12 @@ export default function RswtStat() {
? data.map((item: RswtStatProps) => {
return {
...item,
ctpvCd: item.cityText
ctpvCd: item.ctpvCd
};
})
: [];
setRswtTable(tbData);
}, [rswtStatList])
}, [code, rswtStatList])
useEffect(() => {
const transExcel = Array.isArray(excelList) ? excelList : [excelList];
@@ -58,7 +57,7 @@ export default function RswtStat() {
const tbData = Array.isArray(exData) ?
exData.map((item: RswtStatProps) => {
return {
"시도": item.cityText,
"시도": item.ctpvCd,
"개소": item.ctpvCnt,
"건축연면적(m³)": item.archArea,
"처리용량(m³)": item.filtrTrtmfctCpct,
@@ -76,16 +75,17 @@ export default function RswtStat() {
};
}) : [];
setExceData(tbData);
}, [excelList])
}, [code, excelList])
const excelDetailDownLoad=() =>{
const sidoList = new Set();
const sidoDataMap = new Map(); // 시도별 데이터를 저장할 Map
const sidoList = new Set<string>();
const sidoDataMap = new Map<string, (string | number)[]>(); // 시도별 데이터를 저장할 Map
const sidoDetailMap = new Map<string, (string | number)[][]>(); // 시도별 상세 데이터를 저장할 Map
// 먼저 시도별 상세 데이터를 그룹화
rswtDetailList.forEach((item: RswtStatProps[]) => {
const sidoVal = item.at(0)?.toString().trim();
const sigunVal = item.at(1)?.toString().trim();
const bdstVal = item.at(2)?.toString().trim();
let sidoText = '';
let sigunText = '';
@@ -106,7 +106,15 @@ export default function RswtStat() {
item[2] = sidoText+' '+sigunText as unknown as RswtStatProps;
}
// 시도별 데이터 수집
// 시도별 상세 데이터 수집
if (sidoText) {
if (!sidoDetailMap.has(sidoText)) {
sidoDetailMap.set(sidoText, []);
}
sidoDetailMap.get(sidoText)!.push(item as unknown as (string | number)[]);
}
// 시도별 합계 데이터 수집
if (sidoText && !sidoList.has(sidoText)) {
sidoList.add(sidoText);
// 시도별 초기 데이터 구조 생성 (예: [시도명, 0, 0, 0, ...])
@@ -118,11 +126,12 @@ export default function RswtStat() {
sidoDataMap.set(sidoText, initialData);
}
});
// 시도별 합계 계산
rswtDetailList.forEach((item: RswtStatProps[]) => {
const sidoText = item[0]?.toString();
if (sidoText && sidoDataMap.has(sidoText)) {
const sidoData = sidoDataMap.get(sidoText);
const sidoData = sidoDataMap.get(sidoText)!;
// 각 컬럼의 값을 합계에 더하기 (1번 인덱스부터 시작)
for (let i = 1; i < item.length && i < sidoData.length; i++) {
if(i == 2){
@@ -168,13 +177,31 @@ export default function RswtStat() {
}
}
});
// Map을 배열로 변환
// 시도별로 합계와 상세 데이터를 순서대로 배치
const summaryExcelData: (string | number)[][] = [];
// 시도별로 순회하면서 합계와 상세 데이터를 추가
Array.from(sidoList).forEach((sidoText) => {
const sidoSummary = sidoDataMap.get(sidoText);
const sidoDetails = sidoDetailMap.get(sidoText) || [];
if (sidoSummary) {
// 시도 합계 데이터 추가
summaryExcelData.push(sidoSummary);
// 해당 시도의 상세 데이터들 추가
sidoDetails.forEach(detail => {
summaryExcelData.push(detail);
});
}
});
const sidoSummaryList = Array.from(sidoDataMap.values());
// sidoSummaryList와 rainDetailList를 합쳐서 엑셀 데이터 생성
const excelData = [...sidoSummaryList, ...rswtDetailList];
const excelData = [...sidoSummaryList, ...summaryExcelData];
excelDownload(
excelData,
excelData as unknown as [][],
"중수도시설 통계",
"sample_rswtStats.xlsx",
"A1:Q3",