【问题标题】:C# Reading CSV File | with header Row and Comma Separated ValuesC# 读取 CSV 文件 |带有标题行和逗号分隔值
【发布时间】:2018-08-26 07:48:26
【问题描述】:

下面是我的 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() 在上述情况下对我来说似乎是个问题。 对于上述场景,我们是否有一个简单的解决方案,我正在考虑在读取 CSV 时使用强类型对象。 上述场景是否适合 CSV 帮助模块@https://joshclose.github.io/CsvHelper/2.x/ 任何建议表示赞赏。

【问题讨论】:

  • 标准的TextFieldParser 应该是正确的。见.HasFieldsEnclosedInQuotes Property
  • 是的,我知道,您需要添加对Microsoft.VisualBasic 的引用。人们可以做更糟糕的事情:)。无论如何,我对其进行了测试,它确实可以按照您的预期解析字段。

标签: c# csv header csvhelper


【解决方案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 应该自动处理您引用的字段 - 双引号内的分隔符被 default setting of Configuration.Quote 忽略。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-03
    相关资源
    最近更新 更多