summaryrefslogtreecommitdiff
path: root/lib/menu-list/table/excel-export.ts
diff options
context:
space:
mode:
authordujinkim <dujin.kim@dtsolution.co.kr>2025-10-29 07:44:16 +0000
committerdujinkim <dujin.kim@dtsolution.co.kr>2025-10-29 07:44:16 +0000
commitd28c43b2d33bac51c69ac7417a14f9fe83f2a25f (patch)
tree69827e6cc8389ed41a6d1ee5b5c3fe92721cf68b /lib/menu-list/table/excel-export.ts
parent2eb717eb2bbfd97a5f149d13049aa336c26c393b (diff)
(대표님) menu list excel export 개발
Diffstat (limited to 'lib/menu-list/table/excel-export.ts')
-rw-r--r--lib/menu-list/table/excel-export.ts107
1 files changed, 107 insertions, 0 deletions
diff --git a/lib/menu-list/table/excel-export.ts b/lib/menu-list/table/excel-export.ts
new file mode 100644
index 00000000..feba5310
--- /dev/null
+++ b/lib/menu-list/table/excel-export.ts
@@ -0,0 +1,107 @@
+// app/evcp/menu-list/utils/excel-export.ts
+
+import ExcelJS from 'exceljs';
+
+interface MenuExportData {
+ menuPath: string;
+ menuTitle: string;
+ menuDescription?: string | null;
+ menuGroup?: string | null;
+ sectionTitle: string;
+ domain: string;
+ isActive: boolean;
+ manager1Name?: string | null;
+ manager1Email?: string | null;
+ manager2Name?: string | null;
+ manager2Email?: string | null;
+}
+
+export async function exportMenusToExcel(
+ menus: MenuExportData[],
+ translate: (key: string) => string
+) {
+ // 워크북 생성
+ const workbook = new ExcelJS.Workbook();
+ const worksheet = workbook.addWorksheet('메뉴 목록');
+
+ // 헤더 정의
+ worksheet.columns = [
+ { header: '메뉴 경로', key: 'menuPath', width: 40 },
+ { header: '메뉴명', key: 'menuTitle', width: 30 },
+ { header: '설명', key: 'menuDescription', width: 40 },
+ { header: '그룹', key: 'menuGroup', width: 20 },
+ { header: '섹션', key: 'sectionTitle', width: 20 },
+ { header: '도메인', key: 'domain', width: 15 },
+ { header: '상태', key: 'isActive', width: 10 },
+ { header: '담당자1 이름', key: 'manager1Name', width: 20 },
+ { header: '담당자1 이메일', key: 'manager1Email', width: 30 },
+ { header: '담당자2 이름', key: 'manager2Name', width: 20 },
+ { header: '담당자2 이메일', key: 'manager2Email', width: 30 },
+ ];
+
+ // 헤더 스타일 설정
+ worksheet.getRow(1).font = { bold: true };
+ worksheet.getRow(1).fill = {
+ type: 'pattern',
+ pattern: 'solid',
+ fgColor: { argb: 'FFE0E0E0' }
+ };
+ worksheet.getRow(1).alignment = { vertical: 'middle', horizontal: 'center' };
+
+ // 데이터 추가 (번역 적용)
+ menus.forEach((menu) => {
+ worksheet.addRow({
+ menuPath: menu.menuPath,
+ menuTitle: translate(menu.menuTitle),
+ menuDescription: menu.menuDescription ? translate(menu.menuDescription) : '',
+ menuGroup: menu.menuGroup ? translate(menu.menuGroup) : '',
+ sectionTitle: translate(menu.sectionTitle),
+ domain: menu.domain.toUpperCase(),
+ isActive: menu.isActive ? '활성' : '비활성',
+ manager1Name: menu.manager1Name || '',
+ manager1Email: menu.manager1Email || '',
+ manager2Name: menu.manager2Name || '',
+ manager2Email: menu.manager2Email || '',
+ });
+ });
+
+ // 모든 셀에 테두리 추가
+ worksheet.eachRow((row, rowNumber) => {
+ row.eachCell((cell) => {
+ cell.border = {
+ top: { style: 'thin' },
+ left: { style: 'thin' },
+ bottom: { style: 'thin' },
+ right: { style: 'thin' }
+ };
+ // 데이터 행은 세로 가운데 정렬
+ if (rowNumber > 1) {
+ cell.alignment = { vertical: 'middle', wrapText: true };
+ }
+ });
+ });
+
+ // 자동 필터 추가
+ worksheet.autoFilter = {
+ from: 'A1',
+ to: `K${menus.length + 1}`
+ };
+
+ // 파일 다운로드
+ const buffer = await workbook.xlsx.writeBuffer();
+ const blob = new Blob([buffer], {
+ type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
+ });
+
+ // 다운로드 링크 생성
+ const url = URL.createObjectURL(blob);
+ const link = document.createElement('a');
+ const fileName = `메뉴목록_${new Date().toISOString().slice(0, 10)}.xlsx`;
+
+ link.href = url;
+ link.download = fileName;
+ link.click();
+
+ // 메모리 정리
+ URL.revokeObjectURL(url);
+} \ No newline at end of file