CSVHelper:使用IndexAttribute来写出一个空字段

时间:2019-06-06 16:55:11

标签: c# .net-core csvhelper delimited-text

我们有一个固定的输出记录格式,其中所有字段都用竖线分隔。布局是固定的,但是必填字段不是按顺序排列的(由于客户使用的是现有布局,因此无法更改)。我们可以使用CSVHelper和Index属性来写出空白字段吗,例如[Index(1)],[Index(4)],[Index(7)]会产生类似以下内容:

"Field1Value,,,Field2Value,,,Field3Value"?

我们最终可能会添加缺少的字段,但是必须分阶段考虑(由于客户的影响),但是希望能够创建具有所需字段值的最小输出记录格式。

我们正在与.Net Core 2.2 / C#共同努力。

我看了几个支持使用[Column(xx)]和[FieldOrder(xx)]等数据属性修饰属性的nuget和其他库,但由于它看起来健壮且用途广泛,因此选择了CSVHelper。

public class Person
{
    [Index(1)]
    public string Name { get; set; }
    [Index(4)]
    public short Age { get; set; }
    [Index(7)]
    public string StreetAddress { get; set; }
}

static void Main(string[] args)
{
    var records = new List<Person>
    {
        new Person { Name = "Jon Doe", Age = 100, StreetAddress = "123 Market Place" }
    };

    using (var writer = new StreamWriter("C:\\Projects\\CsvHelperDemo\\file.csv"))
    using (var csv = new CsvWriter(writer))
    {
        csv.WriteRecords(records);
    }
}

预期:

Name,,,Age,,,StreetAddress
Jon Doe,,,100,,,123 Market Place

实际:

Name,Age,StreetAddress
Jon Doe,100,123 Market Place

1 个答案:

答案 0 :(得分:1)

如果这是一个选项,我只需将属性添加到Person类中。如果未填充它们,那么您将只有列名,而列名下面没有数据。有点奇怪,但与“空白”列名和空列没有太大区别。

但是,如果您想获得要描述的结果,可以这样做:

public class Person
{
    [Index(0)]
    public string Name { get; set; }

    [Index(3)]
    public short Age { get; set; }

    [Index(6)]
    public string StreetAddress { get; set; }

    #region For spacing only

    [Name("")]
    [Index(1)]
    public string Abc { get; set; }

    [Name("")]
    [Index(2)]
    public string Xyz { get; set; }

    [Name("")]
    [Index(4)]
    public string Foo { get; set; }

    [Name("")]
    [Index(5)]
    public string Blarg { get; set; }

    #endregion
}

我用假名字。您可以改用真实的。没关系,因为列标题将为空白。

一个缺点是您可以开始填充您现在不使用的那些额外属性之一,然后该列将被填充而没有标题,除非您记得返回并删除[Name(""}]属性。

您还可以创建一个单独的继承类而无需更改Person。这样,您就可以填充Person,然后将其映射到继承的类并用于编写:

public class PersonWithExtraFields : Person
{
    [Name("")]
    [Index(1)]
    public string Abc { get; set; }

    [Name("")]
    [Index(2)]
    public string Xyz { get; set; }

    [Name("")]
    [Index(4)]
    public string Foo { get; set; }

    [Name("")]
    [Index(5)]
    public string Blarg { get; set; }
}

这是一个字面意义的答案,描述了如何使用CsvHelper进行操作。这是一种更简单的方法:

public class PersonCsvWriter
{
    public void Write(List<Person> people, string path)
    {
        using (var file = new StreamWriter(path))
        {
            file.WriteLine("Name,,,Age,,,StreetAddress");
            people.ForEach(p => file.WriteLine($"{p.Name},,,{p.Age},,,{p.StreetAddress}"));
        }
    }
}