如何使用CsvHelper将选定的类字段写入CSV?

myW*_*SON 12 .net c# csv csvhelper

CsvHelper用来读取和写入CSV文件很棒,但我不明白如何只写入选定的类型字段.

说我们有:

using CsvHelper.Configuration;

namespace Project
{
    public class DataView
    {
        [CsvField(Name = "N")]
        public string ElementId { get; private set; }

        [CsvField(Name = "Quantity")]
        public double ResultQuantity { get; private set; }

        public DataView(string id, double result)
        {
            ElementId = id;
            ResultQuantity = result;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我们希望CsvField从当前生成的CSV文件中排除"数量" ,例如:

using (var myStream = saveFileDialog1.OpenFile())
{
    using (var writer = new CsvWriter(new StreamWriter(myStream)))
    {
        writer.Configuration.Delimiter = '\t';
        writer.WriteHeader(typeof(ResultView));
        _researchResults.ForEach(writer.WriteRecord);
    }
}
Run Code Online (Sandbox Code Playgroud)

我可以使用什么来动态地从CSV中排除类型字段?

如果有必要,我们可以处理生成的文件,但我不知道如何删除整个CSV列CsvHelper.

Mar*_*mus 14

我最近需要通过确定在运行时包含哪些字段来实现类似的结果.这是我的方法:

  1. 创建一个映射文件,通过将枚举传入类构造函数来映射运行时需要的字段

    public sealed class MyClassMap : CsvClassMap<MyClass>
    {
        public MyClassMap(ClassType type)
        {
            switch (type)
            {
                case ClassType.TypeOdd
                    Map(m => m.Field1);
                    Map(m => m.Field3);
                    Map(m => m.Field5);                 
                    break;
                case ClassType.TypeEven:
                    Map(m => m.Field2);
                    Map(m => m.Field4);
                    Map(m => m.Field6);                 
                    break;
                case ClassType.TypeAll:
                    Map(m => m.Field1);
                    Map(m => m.Field2);
                    Map(m => m.Field3);
                    Map(m => m.Field4);
                    Map(m => m.Field5);
                    Map(m => m.Field6);                 
                    break;
            }
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. 使用映射配置写出记录

    using (var memoryStream = new MemoryStream())
    using (var streamWriter = new StreamWriter(memoryStream))
    using (var csvWriter = new CsvWriter(streamWriter))
    {
        csvWriter.Configuration.RegisterClassMap(new MyClassMap(ClassType.TypeOdd));
        csvWriter.WriteRecords(records);
        streamWriter.Flush();
        return memoryStream.ToArray();
    }
    
    Run Code Online (Sandbox Code Playgroud)


Joe*_*orn 9

像这样标记字段:

[CsvField( Ignore = true )]
public double ResultQuantity { get; private set; }
Run Code Online (Sandbox Code Playgroud)

更新:没关系。我看到您想在运行时执行此操作,而不是在编译时执行此操作。对于可能犯同样错误的其他人,我会将其作为危险信号。

  • 他们替换为“[忽略]” (5认同)
  • 并且,`CsvFieldAttribute` 在 2.0 版中被删除。 (4认同)

小智 6

你可以这样做:

using (var myStream = saveFileDialog1.OpenFile())
{
    using (var writer = new CsvWriter(new StreamWriter(myStream)))
    {
        writer.Configuration.AttributeMapping(typeof(DataView)); // Creates the CSV property mapping
        writer.Configuration.Properties.RemoveAt(1); // Removes the property at the position 1
        writer.Configuration.Delimiter = "\t";
        writer.WriteHeader(typeof(DataView));
        _researchResults.ForEach(writer.WriteRecord);
    }
}
Run Code Online (Sandbox Code Playgroud)

我们将强制创建属性映射,然后对其进行修改,从而动态删除该列。

  • 这是旧版本的CsvHelper吗?当我深入到writer.configuration中时,AttributeMapping和Properties不存在? (7认同)

Ahm*_*nna 5

我的代码有类似的问题,我通过以下代码修复了它。

你可以这样做:

var ignoreQuantity = true;
using (var myStream = saveFileDialog1.OpenFile())
{
    using (var writer = new CsvWriter(new StreamWriter(myStream)))
    {
        var classMap = new DefaultClassMap<DataView>();
        classMap.AutoMap();
        classMap.Map(m => m.ResultQuantity).Ignore(ignoreQuantity)

        writer.Configuration.RegisterClassMap(classMap);

        writer.Configuration.Delimiter = "\t";
        writer.WriteHeader(typeof(DataView));
        _researchResults.ForEach(writer.WriteRecord);
    }
}
Run Code Online (Sandbox Code Playgroud)