엑셀 양식 다운로드 받는 부분 완료.

This commit is contained in:
truthwing
2025-04-25 13:35:43 +09:00
parent 80aa1d1179
commit be72b89edd
9 changed files with 260 additions and 138 deletions
@@ -0,0 +1,57 @@
import type { chHeadType } from "@/app/store/prfmncReg/chkgdnReg/rainChkgdn";
import type { TableTripleProps } from "@/app/store/ruseFcltMng/fcltReg/rainReg";
import { TableHead, TableRow } from "@common/components/ui";
export const headMakeTriple = (
upHeadList: TableTripleProps[],
makeHeadNm: chHeadType[],
rowCount: number = 2
) => {
return (
<>
{Array.from({ length: rowCount }).map((_, i) => (
<TableRow key={i}>
{upHeadList
.filter((head: TableTripleProps) => head.visible == true)
.map((head: TableTripleProps) =>
!head.upSequnce[i] ? (
<TableHead
className={`border border-gray-600 px-2 py-1 `}
rowSpan={2}
key={head.id}
>
{head.title}
</TableHead>
) : head.upSequnce[i] === 1 ? (
<TableHead
className={`border border-gray-600 px-2 py-1 `}
key={head.id}
rowSpan={1}
colSpan={
makeHeadNm.find((ch) => ch.headNm === head.upName[i])
?.length
}
>
{makeHeadNm.find((ch) => ch.headNm === head.upName[i])?.text}
</TableHead>
) : null
)}
</TableRow>
))}
<TableRow>
{upHeadList.map((head: TableTripleProps) =>
makeHeadNm.find(
(ch) => ch.headNm === head?.upName[1] && head.visible == true
) ? (
<TableHead
className={`border border-gray-600 px-2 py-1 `}
key={head.id}
>
{head.title}
</TableHead>
) : null
)}
</TableRow>
</>
);
};
@@ -1,13 +1,12 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
"use client";
import { useWrStore } from "@/app/store";
import { btnClass } from "@/app/store/common/code";
import type { chHeadType } from "@/app/store/prfmncReg/chkgdnReg/rainChkgdn";
import type { TableTripleProps } from "@/app/store/ruseFcltMng/fcltReg/rainReg";
import { tableData } from "@/components/lib/func/commom";
import HeadChModal from "@/components/ui/modal/headChModal/headChModal";
import {
ContentsDiv,
filePickedBlob,
SearchBaseForm,
Title,
UiModal,
@@ -15,94 +14,36 @@ import {
type ReturnType
} from "@common/business_components/ui";
import ListDiv from "@common/business_components/ui/list_div";
import { Button, TableHead, TableRow } from "@common/components/ui";
import { useEffect, useRef, useState } from "react";
export const headMakeTriple = (
upHeadList: TableTripleProps[],
makeHeadNm: chHeadType[],
rowCount: number = 2
) => {
return (
<>
{Array.from({ length: rowCount }).map((_, i) => (
<TableRow key={i}>
{upHeadList
.filter((head: TableTripleProps) => head.visible == true)
.map((head: TableTripleProps) =>
!head.upSequnce[i] ? (
<TableHead
className={`border border-gray-600 px-2 py-1 `}
rowSpan={2}
key={head.id}
>
{head.title}
</TableHead>
) : head.upSequnce[i] === 1 ? (
<TableHead
className={`border border-gray-600 px-2 py-1 `}
key={head.id}
rowSpan={1}
colSpan={
makeHeadNm.find((ch) => ch.headNm === head.upName[i])
?.length
}
>
{makeHeadNm.find((ch) => ch.headNm === head.upName[i])?.text}
</TableHead>
) : null
)}
</TableRow>
))}
<TableRow>
{upHeadList.map((head: TableTripleProps) =>
makeHeadNm.find(
(ch) => ch.headNm === head?.upName[1] && head.visible == true
) ? (
<TableHead
className={`border border-gray-600 px-2 py-1 `}
key={head.id}
>
{head.title}
</TableHead>
) : null
)}
</TableRow>
</>
);
};
import { Button } from "@common/components/ui";
import { useCallback, useEffect, useRef, useState } from "react";
import { headMakeTriple } from "./TableHead";
export default function RainSttn() {
const { code, rain, init, sttnCommon } = useWrStore((state) => state);
const { code, rain, init, sttnCommon, excelExportAction } = useWrStore((state) => state);
const { rainRes } = rain;
const [isChHead, setIsChHead] = useState(false);
const ref = useRef<ReturnType>({} as ReturnType);
const [bdstTable, setBdstTable] = useState<any[]>();
const [tableHead, setTableHead] = useState<any[]>([]);
let nodeList = headMakeTriple(
const nodeList = headMakeTriple(
sttnCommon.rainSttHeadList,
sttnCommon.rainSttHeadNm
);
useEffect(() => {
if (!rain.isInit) {
init(undefined);
}
}, [rain.isInit, init]);
useEffect(() => {
if (code.sggCd.length > 0) {
const data = tableData(rainRes, { code });
// data 는 위 JSON 객체라고 가정
// TODO: 이게 뭐하는 작업이지?
const unVisibleHead = sttnCommon.rainSttHeadList.filter(
(item: TableTripleProps) => item.visible === false
);
const chData = data
.map((item: any) => ({
...item,
@@ -115,11 +56,11 @@ export default function RainSttn() {
setBdstTable(chData);
}
}, [code, rainRes, sttnCommon]);
}, [code, rainRes, sttnCommon.rainSttHeadList]);
const excelClick = useCallback(() => {
excelExportAction(code.cityCd, code.sggCd);
},[code.cityCd, code.sggCd, excelExportAction]);
return (
<>
<ContentsDiv>
@@ -146,23 +87,7 @@ export default function RainSttn() {
queryClick={function (returnType: ReturnType): void {
}}
excelClick={function (returnType: ReturnType): void {
//내부적인 파일 샘플 받아서 처리하는 부분 추가.
fetch('/sample_rainy.xlsx', {})
.then(async (response) => {
if (!response.ok) {
throw Error(response.statusText)
}
// 받은 파일 바인너리 처리
const blobRet = await response.blob()
// 받은 파일을 버퍼에 넣는 작업
const arrBuffer = await blobRet.arrayBuffer()
// 버퍼에 있는 엑셀데이터 전달 후 json으로 변환
const ret =await filePickedBlob(arrBuffer)
console.log('ret', ret);
console.log(returnType);
})
}}
excelClick={excelClick}
initClick={function (): void {
}}
btnClass={btnClass}
@@ -13,6 +13,7 @@ import RainChkgdTable from "@/components/ui/table/chkgdTable/rainChkgd/rainChkgd
import RswtChkgdTable from "@/components/ui/table/chkgdTable/rswtChkgd/rswtChkgdTable";
import {
ContentsDiv,
filePickedBlob,
SearchDiv,
SearchFormLeft,
SearchFormRight,
@@ -24,7 +25,7 @@ import {
import ListDiv from "@common/business_components/ui/list_div";
import { TableHead, TableRow } from "@common/components";
import { Button } from "@common/components/ui";
import { useEffect, useState } from "react";
import { useCallback, useEffect, useState } from "react";
export const headMakeprfmnc = (
upHeadList: TableUpperProps[],
@@ -78,7 +79,7 @@ export const headMakeprfmnc = (
//-----------------------
export default function Page() {
const { rainChkgdn, rainChkInit,rainChkDetilUpdate } = useWrStore((state) => {
const { code, rainChkgdn, rainChkInit,rainChkDetilUpdate, excelExportAction } = useWrStore((state) => {
return state;
});
@@ -100,7 +101,24 @@ export default function Page() {
rainChkInit('2024','0');
}
}, [rainChkgdn.isInit, rainChkInit]);
useEffect(() => {
console.log("rainChkgdn.excelList", rainChkgdn.excelList);
if (rainChkgdn.excelList.length === 0) return;
fetch('/sample_rainy.xlsx', {})
.then(async (response) => {
if (!response.ok) {
throw Error(response.statusText)
}
// 받은 파일 바인너리 처리
const blobRet = await response.arrayBuffer()
// 버퍼에 있는 엑셀데이터 전달 후 json으로 변환
const ret =await filePickedBlob(blobRet, rainChkgdn.excelList)
console.log('ret', ret);
})
}, [rainChkgdn.excelList]);
const excelClick= useCallback(()=>{
excelExportAction(code.cityCd, code.sggCd);
}, [excelExportAction, code.cityCd, code.sggCd]);
return (
<ContentsDiv>
<div className="grid grid-cols-4 gap-4 ">
@@ -148,9 +166,7 @@ export default function Page() {
<Button
color="green"
size={"sm"}
onClick={() => {
setIsExcel(!isDetail);
}}
onClick={excelClick}
>
양식받기
</Button>
-6
View File
@@ -99,16 +99,10 @@ export type comCodeState = {
bdstUsgCd: SelectDataType[];
cityCd: SelectDataType[];
sggCd: SelectDataType[];
rvbsnCd:SelectDataType[];
mdmbsnCd:SelectDataType[];
lgbsnCd:SelectDataType[];
lclgvrnmntCd:EnvPartSelectDataType[];
orgwtKndCd:SelectDataType[];
yn:SelectDataType[];
};
@@ -0,0 +1,115 @@
import type { SelectDataType } from "@common/business_components"
const useTypes = [
"조경용수",
"청소화장실용수",
"세척살수용수",
"농업용수",
"공업용수",
"친수용수",
"기타"
]
export type ExcelExportType = {
"NO": string,
"시도": string,
"시군구": string,
"상세주소": string,
"시설명": string,
"운영관리형태": string,
"유량측정방법": string,
"연간운영비(원/년)": string,
"점검일": string,
"이용용도": string,
"보급_1월": string,
"보급_2월": string,
"보급_3월": string,
"보급_4월": string,
"보급_5월": string,
"보급_6월": string,
"보급_7월": string,
"보급_8월": string,
"보급_9월": string,
"보급_10월": string,
"보급_11월": string,
"보급_12월": string,
"빗물_1월": string,
"빗물_2월": string,
"빗물_3월": string,
"빗물_4월": string,
"빗물_5월": string,
"빗물_6월": string,
"빗물_7월": string,
"빗물_8월": string,
"빗물_9월": string,
"빗물_10월": string,
"빗물_11월": string,
"빗물_12월": string,
"PH": string,
"탁도": string,
"총대장균군수": string,
"과태료 부과일(위반일)": string,
"위반사항": string,
"과태료부과금액(천원)": string
}
export type Buildingtype = {
bdstInfoPk: number,
ctpvCd: 1,
sggCd: 1001,
daddr: "string3",
bdstNm: "string",
frstArchPrmsnDt: "2025-03-25",
archArea: 0,
regDt: "2025-04-16",
rgtr: null,
mdfcnDt: "2025-04-16",
mdfr: null
}
export const buildingToExcelType = (buildings: Buildingtype[], sidoCode: SelectDataType[], sggCdoe: SelectDataType[]) => {
const excelData: ExcelExportType[] = [];
buildings.forEach((building) => {
useTypes.forEach((useType) => {
excelData.push({
NO: building.bdstInfoPk.toString(),
시도: sidoCode.find((sido) => sido.val === building.ctpvCd.toString())?.text || "",
시군구: sggCdoe.find((sido) => sido.val === building.sggCd.toString())?.text || "",
상세주소: building.daddr,
시설명: building.bdstNm,
운영관리형태: "",
유량측정방법: "",
'연간운영비(원/년)': "",
점검일: "",
이용용도: useType,
보급_1월: "",
보급_2월: "",
보급_3월: "",
보급_4월: "",
보급_5월: "",
보급_6월: "",
보급_7월: "",
보급_8월: "",
보급_9월: "",
보급_10월: "",
보급_11월: "",
보급_12월: "",
빗물_1월: "",
빗물_2월: "",
빗물_3월: "",
빗물_4월: "",
빗물_5월: "",
빗물_6월: "",
빗물_7월: "",
빗물_8월: "",
빗물_9월: "",
빗물_10월: "",
빗물_11월: "",
빗물_12월: "",
PH: "",
탁도: "",
총대장균군수: "",
"과태료 부과일(위반일)": "",
위반사항: "",
"과태료부과금액(천원)": ""
})
})
})
return excelData;
}
@@ -2,8 +2,10 @@ import {
TEST_UUID,
type TableUpperProps,
} from "@/app/store/ruseFcltMng/fcltReg/rainReg";
import { getFetch, postFectch, putFectch } from "@/components/lib/api";
import { fetchType, getFetch, postFectch, putFectch } from "@/components/lib/api";
import type { SelectDataType } from "@common/business_components/ui";
import { z } from "zod";
import { buildingToExcelType, type ExcelExportType } from "./excel";
export const rainChkZod = z.object({
chkgdnPk: z.number(),
@@ -286,6 +288,7 @@ export type rainChkgdnState = {
splHeadList: TableUpperProps[];
rswtDetailHeadList: TableUpperProps[];
isInit: boolean;
excelList:ExcelExportType[]
};
};
@@ -293,6 +296,7 @@ type rainChkgdnActions = {
rainChkInit: (sggCd: string, searchTxt: string) => void;
rainChkDetilUpdate(rainChk: rainChkZodType[]): Promise<void>;
rainChkGuidUpdate(rainChk: rainChkZodType): Promise<void>;
excelExportAction(sidoCode: SelectDataType[],sggCode: SelectDataType[]): Promise<void>
};
export type rainChkgdnType = rainChkgdnState & rainChkgdnActions;
@@ -306,6 +310,7 @@ export const rainChkgdnStateExport: rainChkgdnState = {
ruseHeadList: ruseHeadList,
rswtDetailHeadList: rswtDetailHeadList,
isInit: false,
excelList:[]
},
};
@@ -343,6 +348,16 @@ export const rainChkgdnActionsExport: (set: any) => rainChkgdnActions = (
set: any
) => {
return {
excelExportAction:async(sidoCode:SelectDataType[], sggCode:SelectDataType[])=>{
const data = await getFetch(fetchType.WR, "/reuseFc/building/RNB/0")
const excelList = buildingToExcelType(data, sidoCode, sggCode);
set((state: rainChkgdnState) => ({
rainChkgdn: {
...state.rainChkgdn,
excelList:excelList
},
}));
},
rainChkInit: async (searchTxt: string, sggCd: string) => {
try {
const rainChkRes = await initFetch(searchTxt, sggCd);
@@ -1,11 +1,11 @@
import type { chHeadType } from "@/app/store/prfmncReg/chkgdnReg/rainChkgdn";
import { type ExcelExportType } from "../../../prfmncReg/chkgdnReg/rainChkgdn/excel";
import {
upHeadList,
type TableTripleProps,
type TableUpperProps,
type TableUpperProps
} from "../../fcltReg/rainReg";
export const pbnSttHeadNm: chHeadType[] = [
const pbnSttHeadNm: chHeadType[] = [
{ headNm: "catchment", text: "유역", length: 3 },
{ headNm: "adminDiv", text: "행정구역", length: 2 },
{ headNm: "rusSup", text: "재이용수공급가능량", length: 3 },
@@ -14,7 +14,7 @@ export const pbnSttHeadNm: chHeadType[] = [
];
// id는 다확인해야함
export const pbnSttHeadList: TableUpperProps[] = [
const pbnSttHeadList: TableUpperProps[] = [
{ id: "a", title: "권역", upName: "catchment", upSequnce: 1, visible: true },
{
id: "aaa",
@@ -125,7 +125,7 @@ export const pbnSttHeadList: TableUpperProps[] = [
visible: true,
},
];
export const rainSttHeadNm: chHeadType[] = [
const rainSttHeadNm: chHeadType[] = [
{ headNm: "bdnstInfo", text: "1.건축물정보", length: 9 },
{ headNm: "rainFcltInfo", text: "2.빗물이용시설정보", length: 7 },
{ headNm: "fcltMngInfo", text: "3.시설운영및 이용정보", length: 2 },
@@ -141,7 +141,7 @@ export const rainSttHeadNm: chHeadType[] = [
];
// id는 다확인해야함
export const rainSttHeadList: TableTripleProps[] = [
const rainSttHeadList: TableTripleProps[] = [
{
id: "ctpvCd",
title: "시도",
@@ -342,12 +342,12 @@ export type sttnState = {
pbnSttHeadNm: chHeadType[];
rainSttHeadList: TableTripleProps[];
rainSttHeadNm: chHeadType[];
excelList:ExcelExportType[]
};
};
type sttnActions = {
chSttnHead: (checkList: string[], type: string) => void;
pbnSttnInit: (sggCd: string, searchTxt: string, flg: string) => void;
};
export type sttnType = sttnState & sttnActions;
@@ -358,13 +358,13 @@ export const sttnStateExport: sttnState = {
pbnSttHeadNm: pbnSttHeadNm,
rainSttHeadList: rainSttHeadList,
rainSttHeadNm: rainSttHeadNm,
excelList: [],
},
};
export const sttnActionsExport: (set: any) => sttnActions = (set: any) => {
return {
pbnSttnInit: async (sggCd: string, searchTxt: string, flg: string) => {},
chSttnHead: async (checkList: string[], type: string) => {
const headList =
type === "pbn"
+26 -26
View File
@@ -1,4 +1,20 @@
import { createStore } from "zustand/vanilla";
import { codeActionExport, comCodeStateExport, getCityCd, getEnvPartCd, getMiddleRegionCd, getRegionCd, getSggCd, getUnitWaterShedCd, type comCodeState, type comCodeType } from "./common/code";
import {
matDmdActionsExport,
matDmdStateExport,
type matDmdState,
type matDmdType,
} from "./matDmd";
import { rainChkgdnActionsExport, rainChkgdnStateExport, type rainChkgdnState, type rainChkgdnType } from "./prfmncReg/chkgdnReg/rainChkgdn";
import { rswtChkgdnActionsExport, rswtChkgdnStateExport, type rswtChkgdnState, type rswtChkgdnType } from "./prfmncReg/chkgdnReg/rswrtChkgdn";
import { bdstActionsExport, bdstStateExport, type bdstFulType, type bdstState } from "./ruseFcltMng/fcltReg/bdstReg";
import {
htdflFacActionsExport,
htdflFacStateExport,
type htdflFacState,
type htdflFacType,
} from "./ruseFcltMng/fcltReg/htdflReg";
import {
pubFacActionsExport,
pubFacStateExport,
@@ -17,22 +33,6 @@ import {
type rswtFacState,
type rswtFacType,
} from "./ruseFcltMng/fcltReg/rswtReg";
import {
matDmdActionsExport,
matDmdStateExport,
type matDmdState,
type matDmdType,
} from "./matDmd";
import {
htdflFacActionsExport,
htdflFacStateExport,
type htdflFacState,
type htdflFacType,
} from "./ruseFcltMng/fcltReg/htdflReg";
import { codeActionExport, comCodeStateExport, getCityCd, getEnvPartCd, getMiddleRegionCd, getRegionCd, getSggCd, getUnitWaterShedCd, type comCodeState, type comCodeType } from "./common/code";
import { bdstActionsExport, bdstStateExport, type bdstFulType, type bdstState } from "./ruseFcltMng/fcltReg/bdstReg";
import { rainChkgdnActionsExport, rainChkgdnStateExport, type rainChkgdnState, type rainChkgdnType } from "./prfmncReg/chkgdnReg/rainChkgdn";
import { rswtChkgdnActionsExport, rswtChkgdnStateExport, type rswtChkgdnState, type rswtChkgdnType } from "./prfmncReg/chkgdnReg/rswrtChkgdn";
import { sttnActionsExport, sttnStateExport, type sttnState, type sttnType } from "./ruseFcltMng/fcltSttn/sttn";
export type WrStore = comCodeType&
@@ -72,11 +72,11 @@ export const StoreZus = (
}
) => {
return createStore<WrStore>()((set) => {
getSggCd(set),
getCityCd(set),
getRegionCd(set),
getMiddleRegionCd(set),
getUnitWaterShedCd(set),
getSggCd(set);
getCityCd(set);
getRegionCd(set);
getMiddleRegionCd(set);
getUnitWaterShedCd(set)
getEnvPartCd(set)
return {
...initState,
@@ -85,11 +85,11 @@ export const StoreZus = (
...rswtFacActionsExport(set),
...matDmdActionsExport(set),
...htdflFacActionsExport(set),
...codeActionExport(set),
...bdstActionsExport(set),
...rainChkgdnActionsExport(set),
...rswtChkgdnActionsExport(set),
...sttnActionsExport(set)
...codeActionExport(set),
...bdstActionsExport(set),
...rainChkgdnActionsExport(set),
...rswtChkgdnActionsExport(set),
...sttnActionsExport(set)
};
});
};
+3 -3
View File
@@ -1,11 +1,11 @@
//8880
import { DEV_URL_FO, DEV_URL_WR } from "../config/";
import { DEV_URL_FO, DEV_URL_WR } from "../config/";
export const fetchType={COMMON: "common", WR: "wr"}
export const getFetch = async( type:string , url: string) => {
const div = type === 'common' ? DEV_URL_FO : DEV_URL_WR
const div = type === fetchType.COMMON ? DEV_URL_FO : DEV_URL_WR
const response = await fetch( div+url , {
method: "GET",
headers: {