diff --git a/apps/st/src/components/module/DataGrid.tsx b/apps/st/src/components/module/DataGrid.tsx index 7221186be..2ca17b5c0 100644 --- a/apps/st/src/components/module/DataGrid.tsx +++ b/apps/st/src/components/module/DataGrid.tsx @@ -19,6 +19,8 @@ declare module "realgrid" { summaryMode?: 'aggregate' | 'statistical' | 'none'; checkBar?: { visible?: boolean }; }): void; + setFooters?(footers: Array<{ height?: number }>): void; + setColumnLayout?(layout: unknown[]): void; // footerUserSpans를 포함한 레이아웃 설정 } } @@ -270,7 +272,13 @@ const DataGrid = ({ columnInfo, rowStartNum, isExcelImport = true, isExcelExport // footer가 있는 컬럼이 있으면 footer 높이 설정 const hasFooter = columns.some(col => col.footer); if (hasFooter) { - gridView.footer.height = 40; + // multiRow가 true인 footer가 있으면 멀티푸터 설정 (여러 행) + const hasMultiRowFooter = columns.some(col => col.footer && col.footer.multiRow); + if (hasMultiRowFooter) { + gridView.setFooters?.([{height: 40}, {height: 40}]); + } else { + gridView.footer.height = 40; + } } // 고정 컬럼 설정 @@ -284,6 +292,27 @@ const DataGrid = ({ columnInfo, rowStartNum, isExcelImport = true, isExcelExport summaryMode: "aggregate" }); + // footerUserSpans가 있는 경우 setColumnLayout으로 설정 + const checkFooterUserSpans = (layout: unknown[]): boolean => { + return layout.some(item => { + if (typeof item === 'string') return false; + if (item && typeof item === 'object' && 'footerUserSpans' in item) return true; + if (item && typeof item === 'object' && 'items' in item && Array.isArray(item.items)) { + return checkFooterUserSpans(item.items); + } + return false; + }); + }; + + if (checkFooterUserSpans(columnLayout) && gridView.setColumnLayout) { + // setColumnLayout은 그리드가 완전히 렌더링된 후 호출해야 함 + setTimeout(() => { + if (gridRef.current?.gridView && columnLayout) { + gridRef.current.gridView.setColumnLayout?.(columnLayout); + } + }, 100); + } + // footer의 valueCallback 설정 columns.forEach(col => { if (col.footer && col.footer.valueCallback) { @@ -320,12 +349,12 @@ const DataGrid = ({ columnInfo, rowStartNum, isExcelImport = true, isExcelExport }
- + {columns.map((column) => ( {
number | string; + multiRow?: boolean; // 여러 행 footer 사용 여부 }, }; +export type FooterUserSpan = { + rowspan?: number; // 병합할 행 수 + colspan?: number; // 병합할 컬럼 수 + text?: string; // 표시할 텍스트 +}; + export type ColumnLayoutItem = string | { name: string; hideChildHeaders?: boolean; header: { text: string }; items: (string | ColumnLayoutItem)[]; + footerUserSpans?: FooterUserSpan[]; // footer 병합 설정 +} | { + column: string; // 컬럼 이름 (footerUserSpans 사용 시) + footerUserSpans?: FooterUserSpan[]; // footer 병합 설정 }; export type ColumnInfo = { diff --git a/apps/st/src/components/util/column/review/SeweragePenetrationRateColumnRvw.ts b/apps/st/src/components/util/column/review/SeweragePenetrationRateColumnRvw.ts index fe7869a48..583a72aa2 100644 --- a/apps/st/src/components/util/column/review/SeweragePenetrationRateColumnRvw.ts +++ b/apps/st/src/components/util/column/review/SeweragePenetrationRateColumnRvw.ts @@ -1,9 +1,9 @@ import { ValueType } from "realgrid"; -import type { ColumnConfig } from "@rsone/components"; +import { footerInt, footerDecimal3 } from "@/components/util/grid/footerSummary"; export const SeweragePenetrationRateInfoList = { columns: [ - { name: 'sido', fieldName: '시도', header: { text: '시도' }, mergeCells: true, editable: false, sortdisable: true }, + { name: 'sido', fieldName: '시도', header: { text: '시도' }, mergeCells: true, editable: false, sortdisable: true, footer: { text: '합계', multiRow: true } }, { name: 'sgg', fieldName: '시군구', header: { text: '시군구' }, mergeCells: true, editable: false, sortdisable: true }, { name: '구분', fieldName: '구분', header: { text: '구분' }, editable: false, sortdisable: true }, { name: '수계', fieldName: '수계', header: { text: '수계' } }, @@ -12,12 +12,8 @@ export const SeweragePenetrationRateInfoList = { { name: 'lgbsn', fieldName: '중권역', header: { text: '중권역' } }, { name: 'mdmbsn', fieldName: '소권역', header: { text: '소권역' } }, { name: 'specl_cntrpln_ar', fieldName: '특별대책지역', header: { text: '특별대책지역' } }, - { name: 'total_popl', fieldName: '총인구', header: { text: '총인구' }, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'popl_sm', fieldName: '내국인', header: { text: '내국인' } }, - { name: 'frgnr_popl_sm', fieldName: '외국인', header: { text: '외국인' } }, - { name: 'area', fieldName: '행정참고자료면적(㎢)', header: { text: '행정참고자료면적(㎢)' } }, - { name: 'popltn_sm', fieldName: '총인구(명)', header: { text: '총인구(명)' } }, - { name: 'ar_sm', fieldName: '총면적(㎢)', header: { text: '총면적(㎢)' }, valueType: ValueType.NUMBER }, + { name: 'total_popl', fieldName: '총인구', header: { text: '총인구' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'ar_sm', fieldName: '총면적(㎢)', header: { text: '총면적(㎢)' }, footer: footerDecimal3, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' }, { name: '계', fieldName: '계', header: { text: '계' } }, //공공하수처리인구 { name: '합계', fieldName: '합계', header: { text: '합계' } }, @@ -41,13 +37,16 @@ export const SeweragePenetrationRateInfoList = { { name: 'adtrt_popltn_suprt', fieldName: '고도처리인구보급율(%)', header: { text: `고도처리인구보급율(%)` } }, { name: 'swrg_instlrt', fieldName: '하수도설치율(%)', header: { text: '하수도설치율(%)' } }, { name: 'rmk', fieldName: '비고', header: { text: '비고' } }, - ] as ColumnConfig[], + ], columnLayout: [ { name: 'groupA', hideChildHeaders: false, header: { text: '행정구역' }, - items: ['sido', 'sgg'], + items: [ + { column: 'sido', footerUserSpans: [{ colspan: 3 }] }, + 'sgg', + ] }, '구분', '수계', @@ -59,7 +58,7 @@ export const SeweragePenetrationRateInfoList = { items: ['mdbsn', 'lgbsn', 'mdmbsn'], }, 'specl_cntrpln_ar', - 'popltn_sm', + 'total_popl', 'ar_sm', { name: 'groupD',