import * as XLSX from 'xlsx'; import { type IFileParser, type ParsedSheet } from '@/application/ports/output/IFileParser'; export class SheetJSFileParser implements IFileParser { async parse(file: File): Promise { const extension = file.name.substring(file.name.lastIndexOf('.')).toLowerCase(); if (extension === '.json') { return this.parseJSON(file); } const buffer = await file.arrayBuffer(); const workbook = XLSX.read(buffer, { type: 'array' }); const sheets: ParsedSheet[] = []; for (const sheetName of workbook.SheetNames) { const worksheet = workbook.Sheets[sheetName]; const jsonData = XLSX.utils.sheet_to_json>(worksheet, { defval: '', }); const range = XLSX.utils.decode_range(worksheet['!ref'] ?? 'A1'); const columns: string[] = []; for (let col = range.s.c; col <= range.e.c; col++) { const cellAddress = XLSX.utils.encode_cell({ r: range.s.r, c: col }); const cell = worksheet[cellAddress]; columns.push(cell ? String(cell.v) : `Column${col + 1}`); } sheets.push({ sheetName, columns, rows: jsonData, }); } return sheets; } getSupportedFormats(): string[] { return ['.xlsx', '.xls', '.csv', '.json']; } private async parseJSON(file: File): Promise { const text = await file.text(); const parsed = JSON.parse(text); const dataArray: Record[] = Array.isArray(parsed) ? parsed : [parsed]; const columns = dataArray.length > 0 ? Object.keys(dataArray[0]) : []; return [ { sheetName: file.name.replace(/\.json$/i, ''), columns, rows: dataArray, }, ]; } }