summaryrefslogtreecommitdiff
path: root/lib/menu-list/table/excel-export.ts
blob: feba5310dd9587229e67fd1f32b658dc8ad2b8fb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
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);
}