Présentation

nuiton-csv définit une api simple d'import-export au format CSV. Cette API permet de construire un modèle d'import (et/ou d'export) où les différentes préocupations sont bien séparées.

API

Import

Pour un import, et pour chaque ligne à importer, il y a trois choses à faire :

  • lire la donnée depuis la source d'entrée
  • convertir la donnée en objet
  • persister la donnée convertie dans un objet

La classe org.nuiton.csv.Import permet simplement d'effectuer des imports, une fois le modèle crée.

Export

Pour un export et pour chaque objet à persister dans le fichier CSV, il y a aussi trois choses :

  • lire la donnée depuis l'objet à persister
  • convertir la donnée au format texte
  • persister la donnée convertie dans le flux de sortie

La classe org.nuiton.csv.Export permet simplement d'effectuer un export, une fois le modèle d'export crée et les données à persister récupérées.

API

org.nuiton.csv.ValueFormatter

A faire.

org.nuiton.csv.ValueParser

A faire.

org.nuiton.csv.ValueParserFormatter

A faire.

org.nuiton.csv.ImportModel

A faire.

org.nuiton.csv.ExportModel

A faire.

org.nuiton.csv.ImportExportModel

A faire.

org.nuiton.csv.ModelBuilder

A faire.

org.nuiton.csv.Import

A faire.

org.nuiton.csv.Export

A faire.

Exemple

Construire un modèle d'import/export

A faire...

Importer des données

// création du modèle d'import csv
ImportModel<E> csvModel = null;

// creation d'un importer à partir d'un modèle et d'un reader sur fichier csv
Import<E> importer = Import.newImport(csvModel, reader);

try {

    // parcours des objets crées à partir de chaque ligne du fichier csv
    for (E entity : importer) {

        // A vous :)

    }
} finally {

    // fermeture de l'importer (ne ferme pas le flux d'entrée)
    importer.close();
}

Contrôler les headers pour construire un modèle dynamique

Il est possible, dans un ImportModel de ne définir le modèle qu'après lecture des entêtes du fichier CSV. Cela permet par exemple: - de ne pas rendre certains colonnes absentes obligatoires - de gérer une casse différente de header - d'avoir plusieurs noms différents pour le même header

MyImportModel extends AbstractImportModel<Entity> {

    public MyImportModel() {
        super(';');
    }

    /**
     * Cette méthode sera appelée après lecture des headers et avant la validation des entêtes
     * par rapport au modèle.
     */
    @Override
    public void pushCsvHeaderNames(List<String> headerNames) {
        super.pushCsvHeaderNames(headerNames);

        newMandatoryColumn("Column1");
        newMandatoryColumn("Column2");
        newMandatoryColumn("Column3");
        if (header.contains("Type") {
            newMandatoryColumn("Type");
        } else {
            // nom alternatif de Type = Ref
            newMandatoryColumn("Ref", "Type");
        }
    }
}

Exporter des données

// création du modèle d'export CSV
ExportModel<E> csvModel = null;

// les données à exporter
Iterable<E> datas = null;

// création d'un exporter
Export<E> exporter = Export.newExport(csvModel, datas);

// lancement de l'export vers le fichier
exporter.exportToFile(new File("output.csv"));