Autor Beitrag
DonC
Hält's aus hier
Beiträge: 14



BeitragVerfasst: Mo 03.11.08 13:11 
Hi,

mit folgendem Code erzeuge ich in meinem Programm eine CSV-Datei:

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
private bool exportCSV(string filepath, char separator, ArrayList csv_data)
        {
            bool retVal = true;

            try
            {
                FileStream outStream = new FileStream(filepath, FileMode.OpenOrCreate);
                StreamWriter sw = new StreamWriter(outStream, System.Text.Encoding.Default);
                string csv_line;

                foreach (string[] product in csv_data)
                {
                    csv_line = "";
                    foreach (string value in product)
                    {
                        csv_line = csv_line + value + separator;
                    }
                    sw.WriteLine(csv_line);
                }
                sw.Close();
            }
            catch (Exception e) 
            {
                retVal = false;
            }

            return retVal;
        }


Soweit, so gut. Die Ausgabe ist eine CSV-Datei, in welcher die einzelnen Werte durch Semikolons getrennt sind. Wenn ich diese Datei nun jedoch in Excel öffne, interpretiert er die Semikolons nicht richtig, d.h. er bringt die Spaltenreihenfolge durcheinander, vermischt die erste mit der vierten Spalte und verteilt den Text der vierten Spalte über mehrere Zeilen, obwohl keinerlei Zeilenumbrüche im Text definiert sind. Meine Vermutung ist, dass irgendetwas mit der Zeichenformatierung nicht stimmt, nur was könnte das sein? Wäre super nett, wenn Ihr mir helfen könntet.
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: Mo 03.11.08 13:39 
Ich denke nicht, dass ihm das abschließende Semikolon gefallen wird, benutze lieber String.Join. Ansonsten lässt sich von hier aus wenig sagen, eine Beispieldatei wäre schön.

_________________
>λ=
DonC Threadstarter
Hält's aus hier
Beiträge: 14



BeitragVerfasst: Mo 03.11.08 13:56 
Hi,

ich weiss jetzt glaube ich wo der Hund begraben ist. An dem abschliessenden Semikolon liegt es nicht. In der dritten Spalte enthält der Eingabestring mehrere EOL-Zeichen (End of Line), welche gleichzeitig für einen Zeilenumbruch sorgen. Die Sache ist nämlich, dass der String HTML-Code enthält. Die Lösung meines Problems liegt wohl darin, die EOL-Zeichen aus dem String zu entfernen. Durch ein einfaches Entfernen von Zeilenumbrüchen mit Replace("\n", "") geht das leider nicht. Nur habe ich keine Ahnung, wie man aus einem String die EOL-Zeichen entfernen kann. Vielleicht weiss ja jemand von Euch wie das geht.
JüTho
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2021
Erhaltene Danke: 6

Win XP Prof
C# 2.0 (#D für NET 2.0, dazu Firebird); früher Delphi 5 und Delphi 2005 Pro
BeitragVerfasst: Mo 03.11.08 14:23 
Dann musst Du Dir die Ausgangsdatei in einem Hex-Editor ansehen und prüfen, wie genau das EOL gespeichert ist. "Ausprobieren" für Replace geht noch mit '\r' und '\n' und Environment.NewLine.

Im Übrigen ist statt String.Join noch besser die Verwendung des StringBuilder mit Append. Erklärung: Beim Ändern eines Strings muss immer im Arbeitsspeicher umkopiert werden; das steuert der StringBuilder erheblich besser. Außerdem empfehle ich, statt des StreamWriter File.AppendText zu verwenden.

Noch besser wäre es, alle Zeilen zunächst im Arbeitsspeicher zusammenzustellen; das geht mit dem StringBuilder am einfachsten. Am Schluss wird alles am Stück mit File.WriteAllText gespeichert.

Jürgen
DonC Threadstarter
Hält's aus hier
Beiträge: 14



BeitragVerfasst: Mo 03.11.08 14:59 
user profile iconJüTho hat folgendes geschrieben Zum zitierten Posting springen:
Dann musst Du Dir die Ausgangsdatei in einem Hex-Editor ansehen und prüfen, wie genau das EOL gespeichert ist. "Ausprobieren" für Replace geht noch mit '\r' und '\n' und Environment.NewLine.

Im Übrigen ist statt String.Join noch besser die Verwendung des StringBuilder mit Append. Erklärung: Beim Ändern eines Strings muss immer im Arbeitsspeicher umkopiert werden; das steuert der StringBuilder erheblich besser. Außerdem empfehle ich, statt des StreamWriter File.AppendText zu verwenden.

Noch besser wäre es, alle Zeilen zunächst im Arbeitsspeicher zusammenzustellen; das geht mit dem StringBuilder am einfachsten. Am Schluss wird alles am Stück mit File.WriteAllText gespeichert.

Jürgen


Mit Replace "\r" hat' geklappt. Nun wird die CSV auch korrekt von Excel eingelesen. Besten Dank nochmal :)
Werde den Code auch nochmal nach Deinen Empfehlungen anpassen. Macht auf jeden Fall Sinn.
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: Mo 03.11.08 17:08 
user profile iconJüTho hat folgendes geschrieben Zum zitierten Posting springen:
Im Übrigen ist statt String.Join noch besser die Verwendung des StringBuilder mit Append.
Das finde ich hier unangemessen. Der Flaschenhals ist eindeutig die Festplatte, es spricht nichts dagegen, durch string.Join ein paar Zeilen Code einzusparen. Und wenn er wie bisher zeilenweise schreibt, hat er sogar weniger Speicherverbrauch als mit einem großen StringBuilder.

_________________
>λ=