web-dev-qa-db-fra.com

Pouvez-vous recommander une bibliothèque Java pour lire (et éventuellement écrire) des fichiers CSV?

Pouvez-vous recommander une bibliothèque Java pour lire, analyser, valider et mapper des lignes dans un fichier CSV) à Java (JavaBeans)?

48
Vihung

Nous avons utilisé http://opencsv.sourceforge.net/ avec un bon succès

Je suis également tombé sur une autre question avec de bons liens: bibliothèque Java ou application pour convertir CSV en fichier XML?

37
Gary McWilliams

Super CSV est un excellent choix pour lire/analyser, valider et mapper des fichiers CSV en POJO!

Nous (l'équipe Super CSV) venons de publier une nouvelle version (vous pouvez télécharger à partir de SourceForge ou Maven).

Lecture d'un fichier CSV

L'exemple suivant utilise CsvDozerBeanReader (un nouveau lecteur que nous venons de publier qui utilise Dozer pour le mappage de bean avec un mappage approfondi et un support de mappage basé sur l'index) - il est basé sur l'exemple de notre site Web . Si vous n'avez pas besoin de la fonctionnalité Dozer (ou si vous voulez simplement une dépendance autonome simple), vous pouvez utiliser CsvBeanReader à la place (voir ceci exemple de code ).

Exemple de fichier CSV

Voici un exemple de fichier CSV qui représente les réponses à une enquête. Il a un en-tête et 3 lignes de données, toutes avec 8 colonnes.

age,consentGiven,questionNo1,answer1,questionNo2,answer2,questionNo3,answer3
18,Y,1,Twelve,2,Albert Einstein,3,Big Bang Theory
,Y,1,Thirteen,2,Nikola Tesla,3,Stargate
42,N,1,,2,Carl Sagan,3,Star Wars

Définition du mappage de CSV vers POJO

Chaque ligne de CSV sera lue dans une classe SurveyResponse , chacune ayant une liste de Answer s. Pour que le mappage fonctionne, vos classes doivent être des Javabeans valides (c'est-à-dire avoir un constructeur sans argument par défaut et avoir des getters/setters définis pour chaque champ).

Dans Super CSV, vous définissez le mappage avec un simple tableau de chaînes - chaque élément du tableau correspond à une colonne du fichier CSV.

Avec CsvDozerBeanMapper, vous pouvez utiliser:

  • mappages de champs simples (par exemple firstName)

  • mappages profonds (par exemple address.country.code)

  • mappage indexé (par exemple middleNames[1] - index de base zéro pour les tableaux ou les collections)

  • cartographie profonde + indexée (par exemple person.middleNames[1])

Ce qui suit est le mappage de champ pour cet exemple - il utilise une combinaison de ceux-ci:

private static final String[] FIELD_MAPPING = new String[] { 
        "age",                   // simple field mapping (like for CsvBeanReader)
        "consentGiven",          // as above
        "answers[0].questionNo", // indexed (first element) + deep mapping
        "answers[0].answer", 
        "answers[1].questionNo", // indexed (second element) + deep mapping
        "answers[1].answer", 
        "answers[2].questionNo", 
        "answers[2].answer" };

Conversion et validation

Super CSV possède une bibliothèque utile de processeurs de cellules , qui peut être utilisée pour convertir les chaînes du fichier CSV en d'autres types de données (par exemple Date, Entier), ou pour effectuer la validation des contraintes (par exemple obligatoire/facultatif , correspondance des expressions rationnelles, vérification de la plage).

L'utilisation de processeurs de cellules est entièrement facultative - sans eux, chaque colonne de CSV sera une chaîne, donc chaque champ doit également être une chaîne.

Voici la configuration du processeur de cellule pour l'exemple. Comme pour le mappage de champ, chaque élément du tableau représente une colonne CSV. Il montre comment les processeurs de cellule peuvent transformer les données CSV en type de données de votre champ et comment ils peuvent être chaînés ensemble.

final CellProcessor[] processors = new CellProcessor[] { 
    new Optional(new ParseInt()), // age
    new ParseBool(),              // consent
    new ParseInt(),               // questionNo 1
    new Optional(),               // answer 1
    new ParseInt(),               // questionNo 2
    new Optional(),               // answer 2
    new ParseInt(),               // questionNo 3
    new Optional()                // answer 3
};

En train de lire

La lecture avec Super CSV est très flexible: vous fournissez votre propre Reader (afin que vous puissiez lire à partir d'un fichier, le chemin de classe, un fichier Zip, etc.), et le délimiteur et le caractère de citation sont configurables via préférences (dont il existe un certain nombre de configurations prédéfinies qui répondent à la plupart des utilisations).

Le code ci-dessous est assez explicite.

  1. Créez le lecteur (avec votre Reader et vos préférences)

  2. (Facultatif) lire l'en-tête

  3. Configurer le mappage du bean

  4. Continuez d'appeler read() jusqu'à ce que vous obteniez un null (fin de fichier)

  5. Fermez le lecteur

Code:

ICsvDozerBeanReader beanReader = null;
try {
    beanReader = new CsvDozerBeanReader(new FileReader(CSV_FILENAME),
        CsvPreference.STANDARD_PREFERENCE);

    beanReader.getHeader(true); // ignore the header
    beanReader.configureBeanMapping(SurveyResponse.class, FIELD_MAPPING);

    SurveyResponse surveyResponse;
    while( (surveyResponse = 
        beanReader.read(SurveyResponse.class, processors)) != null ) {
        System.out.println(
            String.format("lineNo=%s, rowNo=%s, surveyResponse=%s",
                beanReader.getLineNumber(), beanReader.getRowNumber(), 
                surveyResponse));
    }

} finally {
    if( beanReader != null ) {
        beanReader.close();
    }
}

Sortie:

lineNo=2, rowNo=2, surveyResponse=SurveyResponse [age=18, consentGiven=true, answers=[Answer [questionNo=1, answer=Twelve], Answer [questionNo=2, answer=Albert Einstein], Answer [questionNo=3, answer=Big Bang Theory]]]
lineNo=3, rowNo=3, surveyResponse=SurveyResponse [age=null, consentGiven=true, answers=[Answer [questionNo=1, answer=Thirteen], Answer [questionNo=2, answer=Nikola Tesla], Answer [questionNo=3, answer=Stargate]]]
lineNo=4, rowNo=4, surveyResponse=SurveyResponse [age=42, consentGiven=false, answers=[Answer [questionNo=1, answer=null], Answer [questionNo=2, answer=Carl Sagan], Answer [questionNo=3, answer=Star Wars]]]

Plus d'information

Vous pouvez trouver beaucoup plus d'informations sur le site Web !

23
James Bassett

Je peux recommander SuperCSV . Simple à utiliser et a fait tout ce dont j'avais besoin.

7
Domchi

Hé, j'ai un projet open-source pour cela: JFileHelpers . Je pense que le principal avantage est qu'il utilise Java Annotations, jetez un œil:

Si vous avez ce bean:

@FixedLengthRecord()
public class Customer {
    @FieldFixedLength(4)
    public Integer custId;

    @FieldAlign(alignMode=AlignMode.Right)
    @FieldFixedLength(20)
    public String name;

    @FieldFixedLength(3)
    public Integer rating;

    @FieldTrim(trimMode=TrimMode.Right)
    @FieldFixedLength(10)
    @FieldConverter(converter = ConverterKind.Date, 
    format = "dd-MM-yyyy")
    public Date addedDate;

    @FieldFixedLength(3)
    @FieldOptional
    public String stockSimbol;    
}

Et veut analyser ce fichier:

....|....1....|....2....|....3....|....4                
1   Antonio Pereira     10012-12-1978ABC
2   Felipe Coury          201-01-2007
3   Anderson Polga       4212-11-2007DEF      

Tout ce que vous avez à faire est le suivant:

FileHelperEngine<Customer> engine = 
    new FileHelperEngine<Customer>(Customer.class); 
List<Customer> customers = 
    new ArrayList<Customer>();

customers = engine.readResource(
    "/samples/customers-fixed.txt");

En outre, il prend en charge la conversion maître-détail, la date et le format, et bien plus encore. Laissez-moi savoir ce que vous pensez!

Meilleures salutations!

4
kolrie

Je trouve Flatpack pour être vraiment bon avec la gestion des fichiers CSV originaux (échappées, citations, mauvais enregistrements, etc.)

3
ddimitrov

La question CSV File to XML posée précédemment semble répondre à toutes mes questions.

OpenCSV ( http://opencsv.sourceforge.net/ ) établit également une liaison avec JavaBeans à l'aide d'une stratégie de mappage de position de colonne

  ColumnPositionMappingStrategy strat = new ColumnPositionMappingStrategy();
  strat.setType(YourOrderBean.class);
  String[] columns = new String[] {"name", "orderNumber", "id"}; // the fields to bind do in your JavaBean
  strat.setColumnMapping(columns);

  CsvToBean csv = new CsvToBean();
  List list = csv.parse(strat, yourReader);

JSEFA ( http://jsefa.sourceforge.net ) semble également faire tout ce dont j'ai besoin - en particulier la liaison aux objets Java - en plus de prendre en charge FLR et XML

2
Vihung
0
Paul Croarkin

J'ai réussi à analyser et à écrire des fichiers CSV à partir de Java avec OpenCSV . Si vous voulez lire ou écrire une feuille de calcul compatible Excel avec Java, le POI la bibliothèque d'Apache est la voie à suivre.

0
Steve Moyer