import * as ExcelJS from 'exceljs'; import { saveAs } from "file-saver"; /** * 기술영업 벤더 가능 아이템 Import를 위한 Excel 템플릿 파일 생성 및 다운로드 (새로운 스키마 버전) */ export async function exportTechVendorPossibleItemsTemplate() { // 워크북 생성 const workbook = new ExcelJS.Workbook(); workbook.creator = 'Tech Vendor Possible Items Management System'; workbook.created = new Date(); // 워크시트 생성 const worksheet = workbook.addWorksheet('기술영업 벤더 가능 아이템'); // 컬럼 헤더 정의 및 스타일 적용 (새로운 스키마에 맞춰) worksheet.columns = [ { header: '벤더이메일 (필수)', key: 'vendorEmail', width: 30 }, { header: '아이템코드 (필수)', key: 'itemCode', width: 20 }, { header: '공종 (선택)', key: 'workType', width: 15 }, { header: '선종 (선택)', key: 'shipTypes', width: 20 }, { header: '아이템리스트 (선택)', key: 'itemList', width: 35 }, { header: '서브아이템리스트 (선택)', key: 'subItemList', width: 35 }, { header: '벤더코드 (호환성)', key: 'vendorCode', width: 15 }, ]; // 헤더 스타일 적용 const headerRow = worksheet.getRow(1); headerRow.eachCell((cell) => { cell.fill = { type: 'pattern', pattern: 'solid', fgColor: { argb: 'FFE6F3FF' } }; cell.font = { bold: true, color: { argb: 'FF1F4E79' } }; cell.border = { top: { style: 'thin' }, left: { style: 'thin' }, bottom: { style: 'thin' }, right: { style: 'thin' } }; cell.alignment = { vertical: 'middle', horizontal: 'center' }; }); // 샘플 데이터 추가 (새로운 스키마에 맞춰) const sampleData = [ { vendorEmail: 'vendor1@example.com', itemCode: 'ITEM001', workType: '용접', shipTypes: '컨테이너선', itemList: '선체 용접 작업', subItemList: '외판 용접, 내부 구조 용접', vendorCode: 'V001' }, { vendorEmail: 'vendor2@example.com', itemCode: 'ITEM002', workType: '도장', shipTypes: '벌크선', itemList: '선체 도장 작업', subItemList: '프라이머, 탑코트', vendorCode: '' }, { vendorEmail: 'vendor3@example.com', itemCode: 'ITEM003', workType: '기계', shipTypes: '탱커', itemList: '기계 설비 설치', subItemList: '엔진, 펌프, 배관', vendorCode: '' }, { vendorEmail: 'vendor1@example.com', itemCode: 'ITEM004', workType: '용접', shipTypes: '컨테이너선, 벌크선', itemList: '특수 용접 작업', subItemList: '', vendorCode: 'V001' }, { vendorEmail: 'vendor4@example.com', itemCode: 'ITEM005', workType: '', shipTypes: '', itemList: '', subItemList: '', vendorCode: 'V004' }, ]; sampleData.forEach((data) => { const row = worksheet.addRow(data); row.eachCell((cell, colNumber) => { cell.border = { top: { style: 'thin' }, left: { style: 'thin' }, bottom: { style: 'thin' }, right: { style: 'thin' } }; cell.alignment = { vertical: 'middle', horizontal: 'left' }; // 긴 텍스트 필드는 줄바꿈 허용 if (colNumber >= 5 && colNumber <= 6) { // itemList, subItemList cell.alignment = { vertical: 'top', horizontal: 'left', wrapText: true }; } }); }); // 안내사항 워크시트 생성 (새로운 스키마에 맞춰) const guideSheet = workbook.addWorksheet('사용 가이드'); const guideData = [ ['기술영업 벤더 가능 아이템 Import 템플릿 (새로운 스키마)', ''], ['', ''], ['📋 새로운 스키마 특징:', ''], ['- 더욱 구체적인 아이템 정보 관리', ''], ['- 공종과 선종으로 세분화된 분류', ''], ['- 아이템 상세 설명 및 서브 아이템 정보', ''], ['- 중복 아이템도 공종/선종이 다르면 별도 관리', ''], ['', ''], ['📌 필수 입력 필드:', ''], ['1. 벤더이메일: 시스템에 등록된 벤더의 이메일 주소', ''], [' 예: vendor@company.com', ''], ['2. 아이템코드: 처리할 아이템의 고유 코드', ''], [' 예: ITEM001, WELD_001, PAINT_002', ''], ['', ''], ['📝 선택 입력 필드:', ''], ['3. 공종: 작업 유형 분류', ''], [' 예: 용접, 도장, 기계, 전기, 배관 등', ''], ['4. 선종: 적용 가능한 선박 유형', ''], [' 예: 컨테이너선, 벌크선, 탱커, LNG선 등', ''], [' - 여러 선종은 콤마로 구분: "컨테이너선, 벌크선"', ''], ['5. 아이템리스트: 아이템에 대한 상세 설명', ''], [' 예: "선체 용접 작업", "외판 도장 및 마감"', ''], ['6. 서브아이템리스트: 세부 작업 항목들', ''], [' 예: "외판 용접, 내부 구조 용접, 배관 용접"', ''], ['7. 벤더코드: 기존 호환성을 위한 선택 필드', ''], ['', ''], ['🔍 중복 처리 로직:', ''], ['- 동일한 벤더 + 아이템코드 + 공종 + 선종 = 중복으로 처리', ''], ['- 아이템코드가 같아도 공종이나 선종이 다르면 별도 항목', ''], ['- 예: ITEM001 + 용접 + 컨테이너선 ≠ ITEM001 + 도장 + 컨테이너선', ''], ['', ''], ['💡 사용 방법:', ''], ['1. "기술영업 벤더 가능 아이템" 시트에 데이터를 입력하세요', ''], ['2. 필수 필드(벤더이메일, 아이템코드)는 반드시 입력', ''], ['3. 선택 필드는 필요에 따라 입력 (빈 칸으로 두어도 됨)', ''], ['4. 한 벤더가 여러 아이템을 담당할 수 있습니다 (1:N 관계)', ''], ['5. 한 아이템에 여러 벤더를 배정할 수 있습니다 (N:M 관계)', ''], ['6. 파일 저장 후 시스템에서 업로드하세요', ''], ['', ''], ['⚠️ 주의사항:', ''], ['- 벤더이메일은 시스템에 이미 등록된 이메일이어야 함', ''], ['- 이메일 형식 확인: @를 포함한 올바른 이메일 형식', ''], ['- 아이템코드는 특수문자나 공백 주의', ''], ['- 긴 텍스트 필드(아이템리스트, 서브아이템리스트)는 줄바꿈 가능', ''], ['- 오류가 있는 항목은 별도 파일로 다운로드됩니다', ''], ['', ''], ['📊 데이터 예시:', ''], ['벤더이메일: welding@company.com', ''], ['아이템코드: WELD_HULL_001', ''], ['공종: 용접', ''], ['선종: 컨테이너선, 벌크선', ''], ['아이템리스트: 선체 구조 용접 작업', ''], ['서브아이템리스트: 외판 용접, 격벽 용접, 갑판 용접', ''], ['', ''], ['📞 문의사항이 있으시면 시스템 관리자에게 연락하세요.', ''], ]; guideData.forEach((rowData, index) => { const row = guideSheet.addRow(rowData); if (index === 0) { // 제목 스타일 row.getCell(1).font = { bold: true, size: 16, color: { argb: 'FF1F4E79' } }; } else if (rowData[0]?.includes('📋') || rowData[0]?.includes('📌') || rowData[0]?.includes('📝') || rowData[0]?.includes('🔍') || rowData[0]?.includes('💡') || rowData[0]?.includes('⚠️') || rowData[0]?.includes('📊')) { // 섹션 제목 스타일 (이모지 포함) row.getCell(1).font = { bold: true, color: { argb: 'FF1F4E79' } }; } else if (rowData[0]?.includes(':')) { // 일반 제목 스타일 row.getCell(1).font = { bold: true, color: { argb: 'FF1F4E79' } }; } else if (rowData[0]?.includes('-') || rowData[0]?.includes('•') || rowData[0]?.includes('예:')) { // 리스트 아이템 스타일 row.getCell(1).font = { color: { argb: 'FF333333' } }; } }); guideSheet.getColumn(1).width = 80; guideSheet.getColumn(2).width = 20; // 파일 생성 및 다운로드 try { const buffer = await workbook.xlsx.writeBuffer(); const blob = new Blob([buffer], { type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" }); const fileName = `기술영업_벤더_가능_아이템_템플릿_${new Date().toISOString().split('T')[0]}.xlsx`; saveAs(blob, fileName); return { success: true }; } catch (error) { console.error("Excel 템플릿 생성 중 오류:", error); return { success: false, error: error instanceof Error ? error.message : "템플릿 생성 중 오류가 발생했습니다." }; } }