Pouvez-vous recommander une bibliothèque Java pour lire, analyser, valider et mapper des lignes dans un fichier CSV) à Java (JavaBeans)?
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?
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).
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 ).
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
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" };
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
};
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.
Créez le lecteur (avec votre Reader
et vos préférences)
(Facultatif) lire l'en-tête
Configurer le mappage du bean
Continuez d'appeler read()
jusqu'à ce que vous obteniez un null
(fin de fichier)
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]]]
Vous pouvez trouver beaucoup plus d'informations sur le site Web !
Je peux recommander SuperCSV . Simple à utiliser et a fait tout ce dont j'avais besoin.
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!
Je trouve Flatpack pour être vraiment bon avec la gestion des fichiers CSV originaux (échappées, citations, mauvais enregistrements, etc.)
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
Voir CVSBeans