Puoi consigliare una libreria Java per leggere (e possibilmente scrivere) file CSV? [chiuso]
Domanda
Puoi consigliare una libreria Java per leggere, analizzare, convalidare e mappare le righe in un file con valori separati da virgola (CSV) su oggetti valore Java (JavaBeans)?
Soluzione
Abbiamo usato http://opencsv.sourceforge.net/ con buon successo
Ho anche incontrato un'altra domanda con buoni collegamenti: Lib lib o app Java per convertire file CSV in file XML?
Altri suggerimenti
Super CSV è un'ottima scelta per leggere / analizzare, convalidare e mappare i file CSV su POJO!
Noi (il team Super CSV) abbiamo appena rilasciato una nuova versione (puoi download da SourceForge o Maven).
Lettura di un file CSV
L'esempio seguente utilizza CsvDozerBeanReader
(un nuovo lettore che abbiamo appena rilasciato che utilizza Dozer per la mappatura dei bean con deep mapping e supporto per la mappatura basata su indice) - si basa sull'esempio del nostro sito Web . Se non hai bisogno della funzionalità Dozer (o vuoi solo una semplice dipendenza autonoma), puoi invece usare CsvBeanReader
(vedi esempio di codice ).
Esempio di file CSV
Ecco un esempio di file CSV che rappresenta le risposte a un sondaggio. Ha un'intestazione e 3 righe di dati, tutte con 8 colonne.
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
Definizione del mapping da CSV a POJO
Ogni riga di CSV verrà letta in un SurveyResponse , ognuno dei quali ha un Elenco di risposta s. Affinché la mappatura funzioni, le tue classi dovrebbero essere Javabeans validi (cioè avere un costruttore no-arg predefinito e avere getter / setter definiti per ogni campo).
In Super CSV definisci la mappatura con un semplice array String: ogni elemento dell'array corrisponde a una colonna nel file CSV.
Con CsvDozerBeanMapper
puoi usare:
-
mappature semplici dei campi (ad es.
firstName
) -
mappature profonde (ad esempio
address.country.code
) -
mapping indicizzato (ad esempio
middleNames [1]
- indice a base zero per array o raccolte) -
mappatura profonda + indicizzata (ad es.
person.middleNames[1[
)
Di seguito è riportata la mappatura dei campi per questo esempio: utilizza una combinazione di questi:
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" };
Conversione e convalida
Super CSV ha una libreria utile di processori di celle , che può essere utilizzata per convertire le stringhe dal file CSV ad altri tipi di dati (ad es. Data, Numero intero) o per convalidare i vincoli (ad es. obbligatorio / facoltativo, corrispondenza regex, controllo intervallo).
L'uso dei processori di celle è del tutto facoltativo - senza di essi ogni colonna di CSV sarà una stringa, quindi ogni campo deve essere anche una stringa.
La seguente è la configurazione del processore della cella per l'esempio. Come per la mappatura dei campi, ogni elemento dell'array rappresenta una colonna CSV. Dimostra come i processori di celle possono trasformare i dati CSV nel tipo di dati del tuo campo e come possono essere concatenati insieme.
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
};
Lettura
La lettura con Super CSV è molto flessibile: fornisci il tuo Reader
(in modo da poter leggere da un file, il percorso di classe, un file zip, ecc.) e il delimitatore e il carattere di citazione sono configurabili tramite preferenze (di cui esistono diverse configurazioni predefinite che soddisfano la maggior parte degli utilizzi).
Il codice che segue è abbastanza autoesplicativo.
-
Crea il lettore (con il tuo
Reader
e le tue preferenze) -
(Opzionalmente) leggi l'intestazione
-
Configura la mappatura del bean
-
Continua a chiamare
read ()
finché non ottieni unnull
(fine del file) -
Chiudi il lettore
Codice:
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();
}
}
Output:
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]]]
Ulteriori informazioni
Puoi trovare molte più informazioni sul sito web !
Posso raccomandare SuperCSV . Semplice da usare e ha fatto tutto il necessario.
Ehi, ho un progetto open source per questo: JFileHelpers . Penso che il vantaggio principale sia che utilizza Java Annotations, dai un'occhiata:
Se hai questo 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;
}
E vuole analizzare questo file:
....|....1....|....2....|....3....|....4
1 Antonio Pereira 10012-12-1978ABC
2 Felipe Coury 201-01-2007
3 Anderson Polga 4212-11-2007DEF
Tutto quello che devi fare è questo:
FileHelperEngine<Customer> engine =
new FileHelperEngine<Customer>(Customer.class);
List<Customer> customers =
new ArrayList<Customer>();
customers = engine.readResource(
"/samples/customers-fixed.txt");
Inoltre, supporta la conversione dei dettagli principali, la data e il formato e molto altro. Fammi sapere cosa ne pensi!
Cordiali saluti!
Trovo Flatpack di essere davvero bravo a gestire file CSV stravaganti (escape, citazioni, record errati, ecc.)
La domanda da File CSV a XML posta in precedenza sembra rispondere a tutte le mie domande.
OpenCSV ( http://opencsv.sourceforge.net/ ) si lega anche a JavaBeans usando un Strategia di mappatura della posizione della colonna
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);
Anche JSEFA ( http://jsefa.sourceforge.net ) sembra fare tutto ciò di cui ho bisogno, in particolare associazione a oggetti Java - oltre a supportare FLR e XML
Vedi CVSBeans