# CSV parsen mehrere Zeilen



## OnDemand (15. Jul 2016)

Hallo zusammen,

ich habe aus SAP eine CSV bekommen, die es nun mit Java zu lesen gilt. Eigetlich sind alle CSV Dateien so aufgebaut, dass pro Zeile ein Datensatz ausgegeben wird zB:
REnr;Summe;Artikelnr;Beschreibung;
leider habe ich nun eine wie folgt erhalten (ein Datensatz über mehrere Zeilen)
ReNr;Summe;Artikelnr;Beschreibung
Attributnr; Lieferadresse

Im Excel wird es korrekt in eine Zeile geschrieben, aber im Editor ist da irgendwie ein Zeilenumbruch. Mit meinem normalen parser, lese ich Zeile für Zeile, was ja aber zu falschen Daten führt.
Hat jemand ne Idee, was man da machen kann? Den Zeilenumbruch irgendwie enfternen vor dem lesen?!


----------



## JCODA (15. Jul 2016)

Ist jeder Datensatz zweizeilig? Dann verknüpfe zwei Zeilen im Java-Programm. 
Oder soll der Parser allgemein sein? D.h. für alle Formate das richtige parsen? Dann könnte man schauen, ob man durch die Anzahl der Einträge nach einem .split() noch weitere Zeilen lesen muss.


----------



## OnDemand (15. Jul 2016)

Hi, danke für die Antwort. Manche Datensätze haben auch mehere Zeilen. Aber jede neue Zeile fängt mit true an (aktiv == true) vielleicht kann ich das irgendwie mit nutzen


----------



## JStein52 (15. Jul 2016)

Dann poste doch mal ein bis zwei aussagekräftige Zeilen aus deinen Dateien


----------



## OnDemand (15. Jul 2016)

Das kann ich leider nicht machen, sind interne Unternehmensdaten. Aber so sehen 2 Datensätze aus mit veränderten Daten:
//Erster Datensatz Zeile 1-3
1. "true";"100001";"060833.00.00";"589.99";"385.71";"0";"0";"HWVOLL"
2. [*] Farbe blau
3. [*] Ohne Innengestell
// Zweiter Datensatz Zeile 4-5
4. "true";"100002";"060843.00.00";"4444.99";"385.71";"0";"0";"HWVOLL"
5. [*] Mit Innengestell
//Dritter Datensatz usw
4. "true";"100003";"060843.00.00";"4444.99";"385.71";"0";"0";"HWVOLL"
5. [*] Mit Gestänge


----------



## JCODA (15. Jul 2016)

wenn das true immer da ist kannst ja immer weitere Zeilen einlesen, bis das nächste true kommt, dann fängt ein neuer Datensatz an ... oder kann das true auch mal false sein? Falls ja kommen denn weitere boolsche Werte im Datensatz vor? nein? dann prüfe auf beides... ansonsten kann man natürlich noch testen, welche Datentypen wo stehen, also Integer/String/Boolean... aber das scheint mir zunächst die Sache eher zu verkomplizieren.


----------



## JStein52 (15. Jul 2016)

Du musst ja nicht die echten Daten posten, du kannst sie ja verfremden. Fangen denn die Folgezeilen immer mit [*]  an ?


----------



## OnDemand (15. Jul 2016)

Soweit ich es sehe, fängt es immer mit [*] an ich vermute, SAP hat da eine Logik dahin, damit es selber weiß, wann ein neuer Datensatz beginnt. Aber ansonsten fangen ALLE Datensätze mit true an


----------



## JStein52 (15. Jul 2016)

Und interessieren dich auch Inhalte aus den Folgezeilen ? Diese scheinen ja anders aufgebaut zu sein wie die erste Zeile (kein Semikolon als Trenner z.B. ?)


----------



## OnDemand (15. Jul 2016)

Leider ja, das sind quasi Attribute zum Datensatz. Zb steht in der Zeile mit Semikolon eine Hose und [*] ist dann jeweils die Größe. So kannst du dir das vorstellen


----------



## JStein52 (15. Jul 2016)

Ja, ok. Und brauchst du diese Attribute nun auch oder kannst du die einfach überlesen ? Steht da ein Attribut pro Zeile ? In deinem Beispiel sind da nämlich keine Trennzeichen zu erkennen (ausser neue Zeile natürlich)


----------



## OnDemand (15. Jul 2016)

Ja die Attribute brauch ich. Es sollte 1 Attribut per Zeile sein. 

Das ist das Problem dass dort keine Trenner drin sind. Aber excel bekommt das auch hin, dann bekommen wir das erst recht hin


----------



## JStein52 (15. Jul 2016)

Was  meinst du eigentlich damit dass Excel das hinkriegt. Wenn ich mir so eine Datei erstelle dann kann Excel das auch nicht ordentlich einlesen. Er macht halt aus den Folgezeilen auch jeweils neue Zeilen mit einem einzigen Feld.

Edit: das war meine Eingabedatei

```
"true";"100001";"060833.00.00";"589.99";"385.71";"0";"0";"HWVOLL"
[*] Farbe blau
[*] Ohne Innengestell
"true";"100002";"060843.00.00";"4444.99";"385.71";"0";"0";"HWVOLL"
[*] Mit Innengestell
"true";"100003";"060843.00.00";"4444.99";"385.71";"0";"0";"HWVOLL"
[*] Mit Gestänge
```


----------



## OnDemand (15. Jul 2016)

Bei mir geht das mit der original Datei. Weiß auch nicht warum excel das lesen kann aber Notepad++ die Umbrüche erkennt.


----------



## JCODA (15. Jul 2016)

Du kannst ja mal in Notepad++ "alle Zeichen anzeigen" anklicken, vielleicht ist der Zeilenumbruch von einem anderen OS. Die unterscheiden sich nämlich.


----------



## OnDemand (16. Jul 2016)

Hinter jeder Zeile steht ein LF wenn ich das im Notepadd++ anzeigen lasse


----------



## Dompteur (16. Jul 2016)

Wenn ich das recht verstehe, dann hast du bereits ein Programm zum Importieren von CSV-Files.
Dann würde ich einen Arbeitsschritt davor setzen, indem du dein File in das "richtige" CSV Format bringst. Dazu musst du eigentlich nur "\n[*] " durch ";" ersetzen. Danach hast du ein CSV File, in dem jede Zeile einem Satz entspricht.


----------



## OnDemand (17. Jul 2016)

Hallo Dompteur,
das hab ich schon versucht, klappt aber irgendwie nicht habe mit "\n" oder "\\n" auch mit r versucht, aber er ersetzt es einfach nicht.


```
while ((line = reader.readLine()) != null) {

                System.out.println(line);

                String[] parts = line.replaceAll("\\r|\\n", "\";\"").split("\";\"", -1);
}
```


----------



## OnDemand (17. Jul 2016)

Habe grad gesehen, dass die Datensätz mir CR LF in NP++ von ein ander getrennt werden, aber dennoch klappts nicht. die Attribute sind mit LF getrennt, also müsste ja \n mit ; ersetztn klappen, aber das LF wird nicht ersetzt


----------



## Meniskusschaden (17. Jul 2016)

Wenn du zeilenweise einliest (also mit readLine()), bekommst du natürlich immer nur die Daten bis zum nächsten Zeilenende ohne das Zeilenende-Symbol. Da kannst du dann logischerweise kein Zeilenendesymbol mehr ersetzen.


----------



## OnDemand (17. Jul 2016)

Das ist wohl wahr, wie dann? erst mit read() lesen und dann nochmal readLine()?


----------



## tommysenf (17. Jul 2016)

```
List<Article> articles = ...
Article article = null;
for each line in file {
  if line.startsWith("[*]") {
     article.addOption(line);
  } else {
     article = new Article(line.split(";"));
     aricles.add(article);
  }
}
```


----------



## OnDemand (17. Jul 2016)

wäre eine Möglichkeit, danke aber mit dem ersetzten muss es doch auch klappen?!


----------

