/** * Service d'export des données en Excel et PDF */ import * as XLSX from 'xlsx'; import { jsPDF } from 'jspdf'; import autoTable from 'jspdf-autotable'; interface InscriptionExport { nom: string; prenom: string; email: string; codeEtablissement: string; fonction: string; statut: string; dateInscription: Date; } interface SessionInfo { formationNom: string; sessionNom: string; dateDebut: Date; dateFin: Date; lieu: string; } /** * Génère un fichier Excel avec la liste des inscrits */ export function generateExcelExport( sessionInfo: SessionInfo, inscriptions: InscriptionExport[] ): Buffer { // Préparer les données const data = inscriptions.map(i => ({ 'Nom': i.nom, 'Prénom': i.prenom, 'Email': i.email, 'Code établissement': i.codeEtablissement, 'Fonction': i.fonction === 'directeur' ? 'Directeur' : i.fonction === 'chef_service' ? 'Chef de service' : 'Autre', 'Statut': i.statut === 'confirmee' ? 'Confirmée' : i.statut === 'liste_attente' ? 'Liste d\'attente' : 'Annulée', 'Date d\'inscription': i.dateInscription.toLocaleDateString('fr-FR'), })); // Créer le workbook const wb = XLSX.utils.book_new(); // Créer la feuille avec les informations de session const infoData = [ ['Formation', sessionInfo.formationNom], ['Session', sessionInfo.sessionNom], ['Date de début', sessionInfo.dateDebut.toLocaleDateString('fr-FR', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric', hour: '2-digit', minute: '2-digit' })], ['Date de fin', sessionInfo.dateFin.toLocaleDateString('fr-FR', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric', hour: '2-digit', minute: '2-digit' })], ['Lieu', sessionInfo.lieu], ['Nombre d\'inscrits', inscriptions.length.toString()], [], ]; // Créer la feuille principale const ws = XLSX.utils.aoa_to_sheet(infoData); // Ajouter les données des inscrits XLSX.utils.sheet_add_json(ws, data, { origin: -1 }); // Ajouter la feuille au workbook XLSX.utils.book_append_sheet(wb, ws, 'Inscrits'); // Générer le buffer const excelBuffer = XLSX.write(wb, { type: 'buffer', bookType: 'xlsx' }); return excelBuffer; } /** * Génère un fichier PDF avec la liste des inscrits */ export function generatePDFExport( sessionInfo: SessionInfo, inscriptions: InscriptionExport[] ): Buffer { const doc = new jsPDF(); // Titre doc.setFontSize(18); doc.text('Liste des inscrits', 14, 20); // Informations de session doc.setFontSize(10); let yPos = 35; doc.text(`Formation : ${sessionInfo.formationNom}`, 14, yPos); yPos += 6; doc.text(`Session : ${sessionInfo.sessionNom}`, 14, yPos); yPos += 6; doc.text(`Date : ${sessionInfo.dateDebut.toLocaleDateString('fr-FR', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric', hour: '2-digit', minute: '2-digit' })}`, 14, yPos); yPos += 6; doc.text(`Lieu : ${sessionInfo.lieu}`, 14, yPos); yPos += 6; doc.text(`Nombre d'inscrits : ${inscriptions.length}`, 14, yPos); // Tableau des inscrits const tableData = inscriptions.map(i => [ i.nom, i.prenom, i.email, i.codeEtablissement, i.fonction === 'directeur' ? 'Directeur' : i.fonction === 'chef_service' ? 'Chef de service' : 'Autre', i.statut === 'confirmee' ? 'Confirmée' : i.statut === 'liste_attente' ? 'Liste d\'attente' : 'Annulée', ]); autoTable(doc, { startY: yPos + 10, head: [['Nom', 'Prénom', 'Email', 'Code étab.', 'Fonction', 'Statut']], body: tableData, styles: { fontSize: 9 }, headStyles: { fillColor: [37, 99, 235] }, }); return Buffer.from(doc.output('arraybuffer')); } /** * Génère une feuille de présence PDF */ export function generateFeuillePresence( sessionInfo: SessionInfo, inscriptions: InscriptionExport[] ): Buffer { const doc = new jsPDF(); // Titre doc.setFontSize(18); doc.text('Feuille de présence', 14, 20); // Informations de session doc.setFontSize(10); let yPos = 35; doc.text(`Formation : ${sessionInfo.formationNom}`, 14, yPos); yPos += 6; doc.text(`Session : ${sessionInfo.sessionNom}`, 14, yPos); yPos += 6; doc.text(`Date : ${sessionInfo.dateDebut.toLocaleDateString('fr-FR', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric', hour: '2-digit', minute: '2-digit' })}`, 14, yPos); yPos += 6; doc.text(`Lieu : ${sessionInfo.lieu}`, 14, yPos); // Tableau de présence (uniquement les inscrits confirmés) const inscritsConfirmes = inscriptions.filter(i => i.statut === 'confirmee'); const tableData = inscritsConfirmes.map(i => [ i.nom, i.prenom, i.codeEtablissement, i.fonction === 'directeur' ? 'Directeur' : i.fonction === 'chef_service' ? 'Chef de service' : 'Autre', '', // Colonne signature ]); autoTable(doc, { startY: yPos + 10, head: [['Nom', 'Prénom', 'Code établissement', 'Fonction', 'Signature']], body: tableData, styles: { fontSize: 10, cellPadding: 5 }, headStyles: { fillColor: [37, 99, 235] }, columnStyles: { 4: { cellWidth: 40 }, // Largeur pour la colonne signature }, }); return Buffer.from(doc.output('arraybuffer')); }