C# Чтение CSV-файла | с заголовком Row и значениями, разделенными запятыми
Ниже моя структура CSV (только что взял строку заголовка и первую строку данных.
Header 1,Header 2,Header 3,Header 4,Header5
Value 1,"Value2 a,Value 2b","Value3 a,Value 3b",Value 4,Value5
Я могу читать CSV, читать строку заголовка и строку данных, предполагая, что CSV имеет разделитель запятыми.
Несколько фрагментов кода -
var fileContent = File.ReadAllLines(csvFile.FullName);
List<string> headerValues = null;
List<string> contentAllRows= null;
if (fileContent !=null && fileContent.Any())
{
headerValues = fileContent.First().Split(separators).ToList();
headerValues.ForEach(h => h = h.Trim());
contentAllRows = fileContent.Skip(1).ToList();
}
for (int row = 0; row <= contentAllRows.Count - 1; row++)
{
var column = contentAllRows[row].Split(separators).ToList();
}
Вывод вышеуказанного фрагмента кода
headerValues[0] = "Header 1"
headerValues[1] = "Header 2"
headerValues[2] = "Header 3"
headerValues[3] = "Header 4"
headerValues[4] = "Header5"
contentAllRows ="Value 1,\"Value2 a,Value 2b\",\"Value3 a,Value 3b\",Value 4,Value5"
columns[0] = "Value 1"
columns[1] = "\"Value2 a"
columns[2] = "Value 2b\""
columns[3] = "\"Value3 a"
columns[4] = "Value 3b\""
columns[5] = "Value 4"
columns[6] = "Value5"
Мой ожидаемый результат (для каждого из указанных выше значений заголовка) -
columns[0]="Value 1"
columns[1]="Value2 a,Value 2b"
columns[2]="Value3 a,Value 3b"
columns[3]=""
columns[4]="Value5"
Split()
Мне кажется, проблема в вышеуказанном случае. У нас есть простое решение для вышеупомянутого сценария, я думаю о том, чтобы иметь объекты типа Strongly при чтении CSV. Подходит ли вышеуказанный сценарий к вспомогательному модулю CSV @ https://joshclose.github.io/CsvHelper/2.x/ Любые предложения приветствуются.
1 ответ
Так как вы упомянули возможность использования CsvHelper - это должно быть довольно просто, чтобы вы использовали его для сопоставления прямо с вашим POCO. Предполагая простой объект:
public class Foo
{
public string Bar1 {get;set;}
public string Bar2 {get;set;}
public string Bar3 {get;set;}
public string Bar4 {get;set;}
public string Bar5 {get;set;}
}
Определить карту классов
internal sealed class MyCsvMap : ClassMap<Foo>
{
public MyCsvMap()
{
Map(x => x.Bar1).Name("Header 1");
Map(x => x.Bar2).Name("Header 2");
Map(x => x.Bar3).Name("Header 3");
Map(x => x.Bar4).Name("Header 4");
Map(x => x.Bar5).Name("Header5");
}
}
А потом просто
using (var sr = new StreamReader(csvFile.FullName))
{
using (var csvReader = new CsvReader(sr))
{
csvReader.Configuration.RegisterClassMap<MyCsvMap>();
return csvReader.GetRecords<Foo>().ToList();
}
}
CsvHelper должен автоматически работать с полями в кавычках - разделители в двойных кавычках по умолчанию игнорируются.