Aller au contenu principal
Version: Current 🚀

Import-Export

Description​

Cette librairie Java fournit des fonctionnalités complètes pour l'import et l'export de fichiers Excel (XLSX) et CSV. Elle permet de lire, valider et traiter des données de fichiers spreadsheet, ainsi que de générer des rapports d'erreurs détaillés.

Fonctionnalités​

Import​

  • Lecture de fichiers Excel (XLSX) et CSV
  • Validation des donnĂ©es avec Hibernate Validator
  • Gestion des erreurs avec gĂ©nĂ©ration de rapports dĂ©taillĂ©s
  • Support multi-feuilles pour les fichiers Excel
  • Validation de structure des fichiers
  • Traitement ligne par ligne avec callbacks personnalisĂ©s

Export​

  • GĂ©nĂ©ration de fichiers Excel avec styles et formatage
  • Export CSV avec encodage UTF-8 et BOM
  • Gestion des images dans les fichiers Excel
  • Formules Excel avec calcul automatique
  • Mise en forme conditionnelle
  • Listes dĂ©roulantes et validation de donnĂ©es

Dépendances​

<dependency>
<groupId>ipsosenso.librairies</groupId>
<artifactId>import-export</artifactId>
<version>1.0.0</version>
</dependency>

Dépendances requises​

  • Java 11+
  • Apache POI 5.3.0 (Excel)
  • Apache Commons CSV 1.9.0 (CSV)
  • Spring Framework 5.1.19
  • Hibernate Validator 6.0.21
  • Apache Commons Lang3 3.12.0

Architecture​

Structure du projet​

src/main/java/importexport/
├── exception/ # Exceptions personnalisées
├── reader/ # Composants de lecture
│ ├── csv/ # Lecteurs CSV
│ ├── excel/ # Lecteurs Excel
│ └── shared/ # Composants partagés
├── writer/ # Composants d'écriture
│ ├── csv/ # Écrivains CSV
│ ├── excel/ # Écrivains Excel
│ └── utils/ # Utilitaires d'écriture
└── utils/ # Utilitaires généraux

Utilisation​

1. Import de fichiers​

Configuration du lecteur​

import importexport.reader.shared.SpreadsheetReader;
import importexport.reader.shared.beans.SpreadSheetReaderOptions;
import importexport.reader.shared.lambda.ProcesseurLigne;
import importexport.reader.shared.lambda.ValidateurLigne;

// Configuration des options
SpreadSheetReaderOptions<MyData> options = new SpreadSheetReaderOptions<>();
options.setValidateurLigne((ligne, index) -> {
// Validation personnalisée de la ligne
return validationResults;
});

// Configuration du processeur de ligne
ProcesseurLigne processeur = (ligne, numeroLigne) -> {
// Traitement de chaque ligne
MyData data = parseLine(ligne);
// Sauvegarde ou traitement des données
};

// Construction du lecteur
SpreadsheetReader.Reader<MyData> reader = SpreadsheetReader.Builder
.setSheet(true, processeur, options) // hasHeader=true
.build();

// Lecture du fichier
InputStream fileStream = new FileInputStream("mon_fichier.xlsx");
BiFunction<MessageSource, Locale, ImportReport> reportBuilder =
reader.readFile(fileStream, SpreadsheetType.EXCEL);

// Génération du rapport d'erreurs si nécessaire
ImportReport report = reportBuilder.apply(messageSource, Locale.FRENCH);
if (report.getError() > 0) {
// Traitement des erreurs
byte[] errorReport = SpreadsheetType.EXCEL.getErrorBuilder()
.generateReport(report.getPagesReport());
}

Validation personnalisée​

// Validation de la structure du fichier
ValidateurStructureWorkbook validateurStructure = workbook -> {
if (workbook.getNumberOfSheets() < 1) {
throw new ImportValidationException("workbook.empty");
}
};

// Validation des pages
ValidateurPage validateurPage = page -> {
if (page.getNumberOfColumns() != 5) {
throw new ImportValidationException("page.columns.count");
}
};

// Application des validateurs
SpreadSheetReaderOptions<MyData> options = new SpreadSheetReaderOptions<>();
options.setValidateurPage(validateurPage);

2. Export de fichiers​

Export Excel​

import importexport.writer.excel.ExcelStreamWriter;
import importexport.writer.excel.beans.HeaderOptions;
import importexport.writer.excel.beans.ColumnOptions;

// Création du writer
ExcelStreamWriter writer = new ExcelStreamWriter();

// Configuration des en-tĂŞtes
List<String> headers = Arrays.asList("Nom", "Prénom", "Email", "Téléphone");
HeaderOptions headerOptions = HeaderOptions.defaultHeader()
.withBold()
.frozen()
.skip(0);

writer.writeHeaders(headers, headerOptions);

// Ajout des données
List<List<?>> data = Arrays.asList(
Arrays.asList("Dupont", "Jean", "jean.dupont@email.com", "0123456789"),
Arrays.asList("Martin", "Marie", "marie.martin@email.com", "0987654321")
);

writer.writeLines(data.stream());

// Configuration des colonnes
List<ColumnOptions> columnOptions = Arrays.asList(
ColumnOptions.byNumberOfCharacter(20), // Nom
ColumnOptions.byNumberOfCharacter(20), // Prénom
ColumnOptions.byNumberOfCharacter(30), // Email
ColumnOptions.byNumberOfCharacter(15) // Téléphone
);

writer.columnsOptions(columnOptions);

// Génération du fichier
byte[] excelFile = writer.write();

Export CSV​

import importexport.writer.csv.CSVWriter;

CSVWriter csvWriter = new CSVWriter()
.setSeparator(';')
.setCharset(Charsets.UTF_8);

// Écriture des en-têtes
csvWriter.writeHeaders(headers);

// Écriture des données
csvWriter.writeLines(data.stream());

// Génération du fichier
byte[] csvFile = csvWriter.write();

3. Gestion des erreurs​

Types d'erreurs​

// Erreur de fichier malformé
throw new FichierMalformeException(ligneErreur);

// Erreur de fichier vide
throw new FichierVideException("Aucune ligne trouvée", "xlsx");

// Erreur d'extension de fichier
throw new BadFileExtensionException("spreadsheet.fileExtension",
Collections.singletonList(fileName));

// Erreur de validation
throw new ImportValidationException("validation.field.required",
Collections.singletonList(fieldName));

Génération de rapports d'erreurs​

// Le rapport d'erreur est généré automatiquement lors de la lecture
ImportReport report = reportBuilder.apply(messageSource, locale);

// Statistiques
int successCount = report.getSuccess();
int errorCount = report.getError();

// Rapport détaillé par page
Map<String, ErrorReport> pagesReport = report.getPagesReport();
for (Map.Entry<String, ErrorReport> entry : pagesReport.entrySet()) {
String pageName = entry.getKey();
ErrorReport errorReport = entry.getValue();

List<String> headers = errorReport.getHeaders();
List<List<?>> content = errorReport.getContent();

// Traitement des erreurs de la page
}

Configuration avancée​

Options de lecture​

SpreadSheetReaderOptions<MyData> options = new SpreadSheetReaderOptions<>();

// Validation de ligne
options.setValidateurLigne((ligne, index) -> {
// Validation personnalisée
return validationResults;
});

// Validation de page
options.setValidateurPage(page -> {
// Validation de la structure de la page
});

// Gestion des erreurs post-traitement
options.setPostErreurValidateur((ligne, index, exception) -> {
// Traitement des erreurs après traitement de la ligne
return fieldErrors;
});

// Nombre de colonnes attendues
options.setNombreColonnes(5);

// Ignorer le type de cellule (pour Excel)
options.setIgnoreCellType(true);

Options d'écriture Excel​

// Styles personnalisés
writer.getStyle("currency", style -> {
style.setDataFormat(dataFormat.getFormat("€ #,##0.00"));
});

// Mise en forme conditionnelle
List<CellRangeAddress> ranges = Arrays.asList(
new CellRangeAddress(1, 100, 2, 2) // Colonne C, lignes 2-101
);
writer.addColorScaleFormatting(ranges, Arrays.asList("FF0000", "FFFF00", "00FF00"));

// Formules
Formula formula = new Formula("=SUM(A1:A10)");
writer.writeCell(0, 0, formula);

// Images
File imageFile = new File("logo.png");
writer.writeCell(0, 0, imageFile);

Exemples complets​

Exemple d'import complet​

@Service
public class ImportService {

@Autowired
private MessageSource messageSource;

public ImportResult importUsers(InputStream fileStream, String fileName) {
try {
// Détermination du type de fichier
SpreadsheetType type = SpreadsheetType.fromSuffixe(fileName);

// Configuration du processeur
ProcesseurLigne processeur = (ligne, numeroLigne) -> {
User user = parseUser(ligne);
userService.save(user);
};

// Configuration des options
SpreadSheetReaderOptions<User> options = new SpreadSheetReaderOptions<>();
options.setValidateurLigne(this::validateUser);
options.setPostErreurValidateur(this::handleUserError);

// Construction du lecteur
SpreadsheetReader.Reader<User> reader = SpreadsheetReader.Builder
.setSheet(true, processeur, options)
.build();

// Lecture du fichier
BiFunction<MessageSource, Locale, ImportReport> reportBuilder =
reader.readFile(fileStream, type);

ImportReport report = reportBuilder.apply(messageSource, Locale.FRENCH);

return new ImportResult(report.getSuccess(), report.getError(),
report.getError() > 0 ? generateErrorReport(report) : null);

} catch (Exception e) {
throw new ImportException("Erreur lors de l'import", e);
}
}

private ValidationResults<User> validateUser(List<String> ligne, int index) {
// Validation personnalisée
return validationResults;
}

private List<FieldError> handleUserError(List<String> ligne, int index, Exception ex) {
// Gestion des erreurs
return fieldErrors;
}
}

Exemple d'export complet​

@Service
public class ExportService {

public byte[] exportUsers(List<User> users) {
ExcelStreamWriter writer = new ExcelStreamWriter();

// Configuration des en-tĂŞtes
List<String> headers = Arrays.asList("ID", "Nom", "Prénom", "Email", "Date création");
writer.writeHeaders(headers, HeaderOptions.defaultHeader().withBold().frozen());

// Préparation des données
Stream<List<?>> dataStream = users.stream().map(user -> Arrays.asList(
user.getId(),
user.getNom(),
user.getPrenom(),
user.getEmail(),
user.getDateCreation()
));

writer.writeLines(dataStream);

// Configuration des colonnes
List<ColumnOptions> columnOptions = Arrays.asList(
ColumnOptions.byNumberOfCharacter(10), // ID
ColumnOptions.byNumberOfCharacter(20), // Nom
ColumnOptions.byNumberOfCharacter(20), // Prénom
ColumnOptions.byNumberOfCharacter(30), // Email
ColumnOptions.byNumberOfCharacter(15) // Date
);

writer.columnsOptions(columnOptions);

return writer.write();
}
}

Bonnes pratiques​

  1. Gestion de la mémoire : Utilisez ExcelStreamWriter pour les gros fichiers
  2. Validation : Toujours valider les données avant traitement
  3. Gestion des erreurs : Implémenter des rapports d'erreurs détaillés
  4. Performance : Utiliser des streams pour le traitement des données
  5. Sécurité : Valider les types de fichiers et la taille des uploads

Limitations​

  • Support uniquement des fichiers XLSX (pas XLS)
  • Limitation de la mĂ©moire pour les très gros fichiers Excel
  • Les images dans Excel sont limitĂ©es par la taille de la cellule

Support​

Pour toute question ou problème, consultez la documentation des dépendances :