2016-01-28 14 views
7

Mam ArrayList<Metadata> i chcę wiedzieć, czy istnieje Java API do pracy z plikami CSV, który ma metodę zapisu, która akceptuje ArrayList <> jako parametr podobny do LinqToCsv w. Netto. Jak wiem OpenCSV jest dostępny, ale klasa CsvWriter nie przyjmuje kolekcji. My Metadane Klasa jestJak napisać ArrayList <Object> do pliku csv

public class Metadata{ 
    private String page; 
    private String document; 
    private String loan; 
    private String type; 
} 
ArrayList<Metadata> record = new ArrayList<Metadata>(); 

raz i wypełnić rekord, chcę napisać każdy wiersz w pliku csv. Proszę sugerować.

+0

Dlaczego nie. A co z javacsv? – Satya

Odpowiedz

8

Na pewno będzie mnóstwo API, które zrobi to za Ciebie, ale dlaczego nie zrobić tego samodzielnie dla tak prostego przypadku? Pozwoli to na zaoszczędzenie zależności, co jest korzystne dla każdego projektu o dowolnym rozmiarze.

Utwórz metodę toCsvRow() w Metadata, która łączy ciągi oddzielone przecinkami.

public String toCsvRow() { 
    return Stream.of(page, document, loan, type) 
      .map(value -> value.replaceAll("\"", "\"\"")) 
      .map(value -> Stream.of("\"", ",").anyMatch(value::contains) ? "\"" + value + "\"" : value) 
      .collect(Collectors.joining(",")); 
} 

Zebrano wyniki tego sposobu dla każdego obiektu Metadata oddzielone nowej linii.

String recordAsCsv = record.stream() 
     .map(Metadata::toCsvRow) 
     .collect(Collectors.joining(System.getProperty("line.separator"))); 

EDIT Jeżeli nie być tak szczęśliwy, jak mieć Java 8 i API Stream do Państwa dyspozycji, będzie to niemal tak proste, stosując tradycyjne listy.

public String toCsvRow() { 
    String csvRow = ""; 
    for (String value : Arrays.asList(page, document, loan, type)) { 
     String processed = value; 
     if (value.contains("\"") || value.contains(",")) { 
      processed = "\"" + value.replaceAll("\"", "\"\"") + "\""; 
     } 
     csvRow += "," + processed; 
    } 
    return csvRow.substring(1); 
} 
+0

Tworzy [stream] (https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html#package.description) dowolną liczbę obiektów taki sam typ. Strumienie są nową funkcją Java 8. – Henrik

+0

ok, jestem związany z Javą 7, dlatego nie rozpoznałem Stream.of(). czy jest jakikolwiek sposób, aby to zrobić bez strumienia, np. na Java 7. – Maverick

+0

Oczywiście, mapowanie i zbieranie strumieni jest po prostu ładniejsze. Zobacz zaktualizowaną odpowiedź - powinieneś być w stanie zrobić ostatnią chwilę samodzielnego wstawiania każdego wiersza do oddzielnej linii. – Henrik

1

Korzystając CSVWriter, można konwertować ArrayList do tablicy, i przekazać, że do pisarza.

csvWriter.writeNext(record.toArray(new String[record.size()])); 
+0

to jest java.lang.ArrayStoreException – Maverick

0

Jeśli masz ArrayList obiektów (metadanych w danym przypadku) należy użyć BeanToCSV zamiast CSVWriter.

Możesz zapoznać się z BeanToCSVTest in the opencsv source code, aby dowiedzieć się, jak z niego korzystać.

+0

Zazwyczaj odpowiedzi powinny być samodzielne. Czy możesz dodać niewielki przykładowy kod? Połączony przykład to prawie 500 linii. –

+0

mmmmkay - Co powiesz na testWriteQuotes() test w BeanToCSVTest, który pobiera tablicę testData i wysyła wynik do dostarczonego programu Writer (dla przypadku testowego jest to StringWriter, ponieważ mogę przetestować wynik.) Niestety nie mam zamiaru przyjść odstresowany jak sarkastyczny lub sarkastyczny, ale jestem bezbożnie zajęty i nie mam czasu na pisanie przykładów. Większość openCSV ma testy, które, choć są uznawane za całość, są zbyt duże, aby można je było wykorzystać jako przykład, można traktować indywidualnie jako przykłady W przyszłości spróbuję zawęzić do konkretnych testów, które najlepiej odpowiedzą na pytanie. –