/** * Composable para exportar formularios de catación a PDF * Genera PDFs en formato EVC-IH01 (formulario físico de IHCAFE) */ import { jsPDF } from 'jspdf' import type { Muestra, SesionCatacion } from '~/types/catacion' import { renderizarFormulario } from '~/utils/pdf' const FORMULARIOS_POR_PAGINA = 2 export const usePdfExport = () => { const exportando = ref(false) const error = ref(null) /** * Exporta una muestra individual a PDF */ const exportarMuestra = async ( muestra: Muestra, nombreArchivo?: string ): Promise => { try { exportando.value = true error.value = null const doc = new jsPDF({ orientation: 'portrait', unit: 'mm', format: 'letter', }) renderizarFormulario(doc, muestra, 0) const filename = nombreArchivo || `catacion-${sanitizarNombre(muestra.nombre)}-${Date.now()}.pdf` doc.save(filename) } catch (err) { error.value = err instanceof Error ? err.message : 'Error al exportar PDF' console.error('Error exportando PDF:', err) throw err } finally { exportando.value = false } } /** * Exporta toda la sesión a PDF (máximo 3 formularios por página) */ const exportarSesion = async ( sesion: SesionCatacion, nombreArchivo?: string ): Promise => { try { exportando.value = true error.value = null const doc = new jsPDF({ orientation: 'portrait', unit: 'mm', format: 'letter', }) const muestras = sesion.muestras muestras.forEach((muestra, index) => { const posicionEnPagina = index % FORMULARIOS_POR_PAGINA // Nueva página si es necesario (excepto primera) if (index > 0 && posicionEnPagina === 0) { doc.addPage() } renderizarFormulario(doc, muestra, posicionEnPagina as 0 | 1 | 2) }) const filename = nombreArchivo || `catacion-sesion-${sesion.fecha}.pdf` doc.save(filename) } catch (err) { error.value = err instanceof Error ? err.message : 'Error al exportar PDF' console.error('Error exportando PDF de sesión:', err) throw err } finally { exportando.value = false } } /** * Exporta muestras seleccionadas a PDF */ const exportarMuestrasSeleccionadas = async ( muestras: Muestra[], nombreArchivo?: string ): Promise => { try { exportando.value = true error.value = null if (muestras.length === 0) { throw new Error('No hay muestras seleccionadas para exportar') } const doc = new jsPDF({ orientation: 'portrait', unit: 'mm', format: 'letter', }) muestras.forEach((muestra, index) => { const posicionEnPagina = index % FORMULARIOS_POR_PAGINA // Nueva página si es necesario (excepto primera) if (index > 0 && posicionEnPagina === 0) { doc.addPage() } renderizarFormulario(doc, muestra, posicionEnPagina as 0 | 1 | 2) }) const filename = nombreArchivo || `catacion-seleccion-${Date.now()}.pdf` doc.save(filename) } catch (err) { error.value = err instanceof Error ? err.message : 'Error al exportar PDF' console.error('Error exportando PDFs seleccionados:', err) throw err } finally { exportando.value = false } } return { exportando: readonly(exportando), error: readonly(error), exportarMuestra, exportarSesion, exportarMuestrasSeleccionadas, } } /** * Sanitiza un nombre para usar como nombre de archivo */ function sanitizarNombre(nombre: string): string { return nombre .toLowerCase() .replace(/[^a-z0-9áéíóúñ]/g, '-') .replace(/-+/g, '-') .replace(/^-|-$/g, '') .substring(0, 50) }