Merge branch 'iipbs/sn/ii' into iipbs/sn/dev

This commit is contained in:
swcho
2025-06-26 10:48:04 +09:00
4 changed files with 109 additions and 13 deletions
@@ -1,6 +1,6 @@
'use client'
import { deleteData, getData } from '@/components/lib/api'
import { UiTable, downloadExcel } from '@common/business_components/ui'
import { UiTable, downloadExcelWithKoreanHeaders } from '@common/business_components/ui'
import { zodResolver } from '@hookform/resolvers/zod'
import { useState } from 'react'
import { useForm } from 'react-hook-form'
@@ -138,14 +138,23 @@ const Result = () => {
// 선택된 행 데이터를 Excel 다운로드 형식으로 변환
const excelData = data.content; // 배열로 감싸서 전달
// 파일명 생성 (분석번호 기반)
const fileName = `RDII분석결과_${selectedRowData.rainInfwtAnlsSn}_${selectedRowData.aplcnYm}`;
// 헤더 매핑 정의
const headerMapping: { [key: string]: string } = {
'rainInfwtAnlsSn': 'RDII분석\n일련번호',
'pplMngNo': '관로\n관리번호',
'anlsTm': '분석시각',
'predcOilq': '예측유량'
};
downloadExcel({
// 파일명 생성 (분석번호 기반)
const fileName = `RDII분석결과_${selectedRowData.swageTmplntNm}_${selectedRowData.aplcnYm}_${selectedRowData.rainInfwtAnlsSn}`;
await downloadExcelWithKoreanHeaders({
data: excelData as JSON[],
fileName: fileName,
sheetNameArray: ["RDII 분석결과"],
headerRange: "A1:D1" // 테이블 컬럼 수에 맞춰 조정
headerRange: "A1:D1",
headerMapping: headerMapping
});
setIsLoadingResult(false);
} catch (error) {
@@ -1,6 +1,6 @@
'use client'
import { deleteData, getData } from '@/components/lib/api'
import { UiTable, downloadExcel } from '@common/business_components/ui'
import { UiTable, downloadExcelWithKoreanHeaders } from '@common/business_components/ui'
import { zodResolver } from '@hookform/resolvers/zod'
import { useState } from 'react'
import { useForm } from 'react-hook-form'
@@ -137,14 +137,23 @@ const Result = () => {
// 선택된 행 데이터를 Excel 다운로드 형식으로 변환
const excelData = data.content; // 배열로 감싸서 전달
// 파일명 생성 (분석번호 기반)
const fileName = `침입수분석결과_${selectedRowData.inftwtAnlsSn}_${selectedRowData.aplcnYm}`;
// 헤더 매핑 정의
const headerMapping: { [key: string]: string } = {
'inftwtAnlsSn': '침입수분석\n일련번호',
'pplMngNo': '관로\n관리번호',
'anlsTm': '분석시각',
'predcOilq': '예측유량'
};
downloadExcel({
// 파일명 생성 (분석번호 기반)
const fileName = `침입수분석결과_${selectedRowData.swageTmplntNm}_${selectedRowData.aplcnYm}_${selectedRowData.inftwtAnlsSn}`;
await downloadExcelWithKoreanHeaders({
data: excelData as JSON[],
fileName: fileName,
sheetNameArray: ["침입수 분석결과"],
headerRange: "A1:D1" // 테이블 컬럼 수에 맞춰 조정
headerRange: "A1:D1",
headerMapping: headerMapping
});
setIsLoadingResult(false);
} catch (error) {
@@ -62,4 +62,48 @@ export const excelArrayStyle = async (data: ArrayBuffer, range: SheetParameter[]
}
makeExcelFile(workbook, fileNm)
}
}
export const excelStyleWithKoreanHeaders = async (
data: ArrayBuffer,
range: string = "A1:V3",
fileNm: string,
headerMapping: { [key: string]: string },
sampleData: any
) => {
const workbook = await XlsxPopulate.Workbook.fromData(data);
const sheet = workbook.activeSheet();
if (!sheet) {
throw new Error('워크시트를 찾을 수 없습니다.');
}
// 1. 영문 헤더를 한글로 교체
const englishHeaders = Object.keys(sampleData);
englishHeaders.forEach((englishHeader, index) => {
const koreanHeader = headerMapping[englishHeader] || englishHeader;
const cellAddress = String.fromCharCode(65 + index) + '1'; // A1, B1, C1, ...
sheet.cell(cellAddress).value(koreanHeader);
});
// 2. 헤더 스타일 적용
const headerCells = sheet.range(range);
headerCells?.style((styleQ) => {
makeCellStyle(styleQ);
});
// 3. 모든 데이터 셀에 세로 가운데 정렬 적용
const numCols = englishHeaders.length;
const numRows = sheet.usedRange()?.endCell()?.rowNumber() || 1;
if (numRows > 1) {
const dataRange = sheet.range(`A1:${String.fromCharCode(65 + numCols - 1)}${numRows}`);
dataRange?.style((styleQ) => {
styleQ.verticalAlignment("center");
styleQ.borderEach({ style: "thin", color: { rgb: "CCCCCC" } });
});
}
// 4. 파일 다운로드
await makeExcelFile(workbook, fileNm);
};
@@ -1,5 +1,5 @@
import * as XLSX from 'xlsx';
import { excelArrayStyle, excelStyle } from './excelStyle';
import { excelArrayStyle, excelStyle, excelStyleWithKoreanHeaders } from './excelStyle';
type ExcelDownloadProps = {
data: JSON | JSON[];
@@ -164,4 +164,38 @@ export const filePickedBlobArray = (oFile: ArrayBuffer, fileNm: string, sheetArr
});
await excelArrayStyle(XLSX.write(wb, { bookType: "xlsx", type: "buffer" }), sheetArray, fileNm)
});
}
}
type ExcelDownloadWithHeaderProps = {
data: JSON | JSON[];
fileName: string;
sheetNameArray: string[];
headerRange?: string;
headerMapping: { [key: string]: string };
}
export const downloadExcelWithKoreanHeaders = async ({
data,
fileName = new Date().getTime().toString() + '.xlsx',
sheetNameArray = ["Sheet1"],
headerRange = 'A1:V3',
headerMapping
}: ExcelDownloadWithHeaderProps) => {
const dataArray = Array.isArray(data) ? data : [data];
if (dataArray.length === 0) {
throw new Error('데이터가 없습니다.');
}
// 1. 원본 데이터로 워크시트 생성
const worksheet = XLSX.utils.json_to_sheet(dataArray);
const workbook = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(workbook, worksheet, sheetNameArray[0]);
// 2. 워크북을 ArrayBuffer로 변환
const buffer = XLSX.write(workbook, { bookType: "xlsx", type: "buffer" });
// 3. 헤더만 한글로 교체하는 커스텀 스타일 함수 호출
await excelStyleWithKoreanHeaders(buffer, headerRange, fileName, headerMapping, dataArray[0]);
};