diff options
Diffstat (limited to 'lib/vendor-evaluation-submit/table')
| -rw-r--r-- | lib/vendor-evaluation-submit/table/esg-evaluation-form-sheet.tsx | 115 |
1 files changed, 76 insertions, 39 deletions
diff --git a/lib/vendor-evaluation-submit/table/esg-evaluation-form-sheet.tsx b/lib/vendor-evaluation-submit/table/esg-evaluation-form-sheet.tsx index 4b48407c..8261bb7b 100644 --- a/lib/vendor-evaluation-submit/table/esg-evaluation-form-sheet.tsx +++ b/lib/vendor-evaluation-submit/table/esg-evaluation-form-sheet.tsx @@ -34,6 +34,7 @@ import { AccordionItem, AccordionTrigger, } from "@/components/ui/accordion" +import ExcelJS from "exceljs" import { getEsgEvaluationFormData, @@ -205,51 +206,87 @@ export function EsgEvaluationFormSheet({ } } - // ESG 평가 데이터 내보내기 - const handleExportData = () => { - if (!formData) return +// ESG 평가 데이터 내보내기 +const handleExportData = async () => { + if (!formData) return - // CSV 데이터 생성 - const csvData = [] - csvData.push(['카테고리', '점검항목', '평가항목', '평가항목설명', '답변옵션', '옵션점수']) + // 워크북 및 워크시트 생성 + const workbook = new ExcelJS.Workbook() + const worksheet = workbook.addWorksheet('ESG평가') - formData.evaluations.forEach(evaluation => { - evaluation.items.forEach(item => { - // 각 평가항목에 대해 모든 답변 옵션을 별도 행으로 추가 - item.answerOptions.forEach(option => { - csvData.push([ - evaluation.evaluation.category, - evaluation.evaluation.inspectionItem, - item.item.evaluationItem, - item.item.evaluationItemDescription || '', - option.answerText, - option.score - ]) - }) + // 헤더 정의 + const headers = ['카테고리', '점검항목', '평가항목', '평가항목설명', '답변옵션', '옵션점수'] + + // 데이터 준비 + const data: any[] = [] + let lastKey = '' + + formData.evaluations.forEach(evaluation => { + evaluation.items.forEach(item => { + item.answerOptions.forEach(option => { + // A-D열의 중복 체크를 위한 키 생성 + const currentKey = `${evaluation.evaluation.category}|${evaluation.evaluation.inspectionItem}|${item.item.evaluationItem}|${item.item.evaluationItemDescription}` + + // 중복된 경우 A-D열을 빈 값으로 설정 + const row = lastKey === currentKey + ? ['', '', '', '', option.answerText, option.score] + : [ + evaluation.evaluation.category, + evaluation.evaluation.inspectionItem, + item.item.evaluationItem, + item.item.evaluationItemDescription || '', + option.answerText, + option.score + ] + + data.push(row) + lastKey = currentKey }) }) + }) - // CSV 문자열 생성 - const csvContent = csvData.map(row => - row.map(field => `"${String(field).replace(/"/g, '""')}"`).join(',') - ).join('\n') + // 헤더 추가 및 스타일 적용 + worksheet.addRow(headers) + const headerRow = worksheet.getRow(1) + headerRow.eachCell((cell) => { + cell.fill = { + type: 'pattern', + pattern: 'solid', + fgColor: { argb: 'D3D3D3' } // 회색 배경 + } + cell.font = { bold: true } + cell.alignment = { vertical: 'middle', horizontal: 'center' } + }) - // BOM 추가 (한글 깨짐 방지) - const bom = '\uFEFF' - const blob = new Blob([bom + csvContent], { type: 'text/csv;charset=utf-8;' }) - - // 다운로드 - const link = document.createElement('a') - const url = URL.createObjectURL(blob) - link.setAttribute('href', url) - link.setAttribute('download', `ESG평가문항_${formData.submission.vendorName}_${new Date().toISOString().split('T')[0]}.csv`) - link.style.visibility = 'hidden' - document.body.appendChild(link) - link.click() - document.body.removeChild(link) - - toast.success('ESG 평가 문항이 다운로드되었습니다.') - } + // 데이터 행 추가 + data.forEach((row: any) => { + worksheet.addRow(row) + }) + + // 컬럼 너비 자동 조정 + worksheet.columns.forEach((column, colIndex) => { + let maxWidth = headers[colIndex].length + data.forEach((row: any) => { + const cellValue = row[colIndex] ? String(row[colIndex]) : '' + maxWidth = Math.max(maxWidth, cellValue.length) + }) + column.width = maxWidth + 5 // 여유 공간 추가 + }) + + // 파일 생성 및 다운로드 + const buffer = await workbook.xlsx.writeBuffer() + const blob = new Blob([buffer], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' }) + const link = document.createElement('a') + const url = URL.createObjectURL(blob) + link.setAttribute('href', url) + link.setAttribute('download', `ESG평가문항_${formData.submission.vendorName}_${new Date().toISOString().split('T')[0]}.xlsx`) + link.style.visibility = 'hidden' + document.body.appendChild(link) + link.click() + document.body.removeChild(link) + + toast.success('ESG 평가 문항이 다운로드되었습니다.') +} // 진행률 및 점수 계산 const getProgress = () => { |
