Files
formation-manager-itinova/server/exportService.ts

192 lines
4.9 KiB
TypeScript

/**
* 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;
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,
'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.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.', '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,
'', // Colonne signature
]);
autoTable(doc, {
startY: yPos + 10,
head: [['Nom', 'Prénom', 'Code établissement', 'Signature']],
body: tableData,
styles: { fontSize: 10, cellPadding: 5 },
headStyles: { fillColor: [37, 99, 235] },
columnStyles: {
3: { cellWidth: 40 }, // Largeur pour la colonne signature
},
});
return Buffer.from(doc.output('arraybuffer'));
}