Merge commit '381d95dd753b4af51433dc3d2815399d3223b4df' into iipbs/wr/hasuReg
iipbs_wr / build (push) Waiting to run
iipbs_wr / build (push) Waiting to run
This commit is contained in:
@@ -53,7 +53,8 @@ export const excelArrayStyle = async (data: ArrayBuffer, range: SheetParameter[]
|
||||
if (item.data && item.data.length > 0) {
|
||||
const numCols = item.data[0]?.length || 0;
|
||||
const numRows = item.data.length;
|
||||
const dataRange = workbook.activeSheet(index)?.sheet(index)?.range(`A1:${String.fromCharCode(65 + numCols - 1)}${numRows}`);
|
||||
const lastColLetter = getExcelColumnLetter(numCols);
|
||||
const dataRange = workbook.activeSheet(index)?.sheet(index)?.range(`A1:${lastColLetter}${numRows}`);
|
||||
dataRange?.style((styleQ) => {
|
||||
styleQ.verticalAlignment("center");
|
||||
});
|
||||
@@ -62,4 +63,60 @@ 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);
|
||||
};
|
||||
|
||||
|
||||
const getExcelColumnLetter = (colIndex: number): string => {
|
||||
let letter = '';
|
||||
while (colIndex > 0) {
|
||||
const mod = (colIndex - 1) % 26;
|
||||
letter = String.fromCharCode(65 + mod) + letter;
|
||||
colIndex = Math.floor((colIndex - 1) / 26);
|
||||
}
|
||||
return letter;
|
||||
};
|
||||
|
||||
|
||||
@@ -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]);
|
||||
};
|
||||
@@ -308,7 +308,6 @@ export const FileUploaderItem = forwardRef<
|
||||
{children}
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
className={cn(
|
||||
"absolute",
|
||||
"!w-1/5 z-50",
|
||||
|
||||
@@ -223,7 +223,6 @@ function Gis({ isOpen , gisMaps, isSearchModalOpen, treeData = [], isSearch = fa
|
||||
{isSearch && (
|
||||
<div className="absolute right-8 top-[305px] z-20">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setIsSearchModalOpen(true)}
|
||||
className="overflow-hidden w-[40px] h-[40px] bg-white
|
||||
border border-[#9aa7b8]
|
||||
|
||||
@@ -60,7 +60,6 @@ export default function GisContent({ edit = false, onFeatureSelect, isSearch, se
|
||||
{isSearch && (
|
||||
<div className="absolute right-8 top-[254px] z-20">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setIsSearchModalOpen(true)}
|
||||
className="overflow-hidden w-[40px] h-[40px] bg-white
|
||||
border border-[#9aa7b8]
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
// <TabsTrigger value="layers" className="flex-1 h-10">레이어</TabsTrigger>
|
||||
// {/* {isSearch && (
|
||||
// <button
|
||||
// type="button"
|
||||
// onClick={() => setIsSearchModalOpen(true)}
|
||||
// className="h-10 w-10 flex items-center justify-center px-0"
|
||||
// >
|
||||
|
||||
Reference in New Issue
Block a user