diff --git a/Tasks/CsvBuilder.cs b/Tasks/CsvBuilder.cs index 6365ada..255f190 100644 --- a/Tasks/CsvBuilder.cs +++ b/Tasks/CsvBuilder.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Linq; using System.Text; namespace Logof_Client; @@ -30,34 +31,45 @@ public class CsvBuilder result.AppendLine(Header); foreach (var l in KasAddressList.KasPersons) - - result.AppendLine( - l.refsid + Separator + - l.anrede + Separator + - l.titel + Separator + - l.vorname + Separator + - l.adel + Separator + - l.name + Separator + - l.namezus + Separator + - l.anredzus + Separator + - l.strasse + Separator + - l.strasse2 + Separator + - l.plz + Separator + - l.ort + Separator + - l.land + Separator + - l.pplz + Separator + - l.postfach + Separator + - l.name1 + Separator + - l.name2 + Separator + - l.name3 + Separator + - l.name4 + Separator + - l.name5 + Separator + - l.funktion + Separator + - l.funktion2 + Separator + - l.abteilung + Separator + - l.funktionad); + result.AppendLine(string.Join(Separator, new[] + { + EscapeCsvField(l.refsid.ToString()), + EscapeCsvField(l.anrede), + EscapeCsvField(l.titel), + EscapeCsvField(l.vorname), + EscapeCsvField(l.adel), + EscapeCsvField(l.name), + EscapeCsvField(l.namezus), + EscapeCsvField(l.anredzus), + EscapeCsvField(l.strasse), + EscapeCsvField(l.strasse2), + EscapeCsvField(l.plz), + EscapeCsvField(l.ort), + EscapeCsvField(l.land), + EscapeCsvField(l.pplz), + EscapeCsvField(l.postfach), + EscapeCsvField(l.name1), + EscapeCsvField(l.name2), + EscapeCsvField(l.name3), + EscapeCsvField(l.name4), + EscapeCsvField(l.name5), + EscapeCsvField(l.funktion), + EscapeCsvField(l.funktion2), + EscapeCsvField(l.abteilung), + EscapeCsvField(l.funktionad) + })); // weitere Cases return result.ToString(); } -} \ No newline at end of file + + private string EscapeCsvField(string? value) + { + var field = value ?? string.Empty; + var mustQuote = field.Contains(Separator) || field.Contains('"') || field.Contains('\r') || field.Contains('\n'); + if (!mustQuote) + return field; + + return "\"" + field.Replace("\"", "\"\"") + "\""; + } +} diff --git a/Tasks/DataImport.cs b/Tasks/DataImport.cs index e8f6464..d7e5940 100644 --- a/Tasks/DataImport.cs +++ b/Tasks/DataImport.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; +using System.Text; namespace Logof_Client; @@ -41,7 +42,7 @@ public class DataImport if (string.IsNullOrWhiteSpace(line)) continue; - var parts = line.Split(separator).Select(p => p.Trim()).ToArray(); + var parts = ParseCsvLine(line, separator); if (parts.Length < 24) { @@ -107,7 +108,7 @@ public class DataImport return (false, null); } - var headers = headerLine.Split(separator).Select(h => h.Trim()).ToArray(); + var headers = ParseCsvLine(headerLine, separator); var imported = new KasAddressList(KasAddressList.GenerateName(Path.GetFileNameWithoutExtension(pathToCsv.LocalPath))); @@ -126,7 +127,7 @@ public class DataImport if (string.IsNullOrWhiteSpace(line)) continue; - var parts = line.Split(separator).Select(p => p.Trim()).ToArray(); + var parts = ParseCsvLine(line, separator); var fieldValues = new Dictionary(StringComparer.OrdinalIgnoreCase); @@ -241,4 +242,41 @@ public class DataImport { return int.TryParse(input, out var result) ? result : 0; } -} \ No newline at end of file + + private static string[] ParseCsvLine(string line, char separator) + { + var fields = new List(); + var current = new StringBuilder(); + var inQuotes = false; + + for (var i = 0; i < line.Length; i++) + { + var c = line[i]; + + if (c == '"') + { + if (inQuotes && i + 1 < line.Length && line[i + 1] == '"') + { + current.Append('"'); + i++; + continue; + } + + inQuotes = !inQuotes; + continue; + } + + if (c == separator && !inQuotes) + { + fields.Add(current.ToString().Trim()); + current.Clear(); + continue; + } + + current.Append(c); + } + + fields.Add(current.ToString().Trim()); + return fields.ToArray(); + } +}