CsvHelper 只是为 Class 列表编写 header

CsvHelper just writing header for Class List

这里和 CsvHelper 的文档中有许多使用 CsvHelper 编写 CSV 的例子。 None 确实帮我写了 类

的列表

列表是这些Objects

class Contract
{
    public Contract()
    {
        Id = "None";
        Type = "";
        FileNames = new List<string>();
    }
    public string Id { get; set; }
    public string Type { get; set; }
    public List<String> FileNames { get; set; }
    public override string ToString()
    {
        string result = "Contract:ID " + Id
        + ",Type " + Type
        + ",FileNames ";
        foreach (string FileName in FileNames)
        {
            result = result + FileName + ",";
        }
        return result;
    }
}

这个

    public void SaveCsv(string PathCsv)
    {
        Console.WriteLine("save Contracts to " + PathCsv);

        var config = new CsvConfiguration(CultureInfo.InvariantCulture)
        {
            Delimiter = ";",
            Encoding = Encoding.UTF8
        };
        using (var writer = new StreamWriter(PathCsv))
        using (var csv = new CsvWriter(writer, config))
        {
            csv.WriteHeader<Contract>();
            foreach (var contract in contracts)
            {
                csv.WriteRecord<Contract>(contract);
                csv.NextRecord();
            }
        }
    }

只返回 headers 而没有合同列表。如何正确地将合同列表写成 csv?

如果你知道文件名的数量,你可以像这样写出 header,使用 ClassMap.Index() 以及开始和结束索引。

Id;Type;FileName1;FileName2;FileName3

void Main()
{
    var records = new List<Contract>
    {
        new Contract { Id = "First", Type = "MyType", FileNames = new List<string> {"one","two","three"} },
        new Contract { Id = "Second", Type = "MyOtherType", FileNames = new List<string> {"four","five","six"} }
    };

    var config = new CsvConfiguration(CultureInfo.InvariantCulture)
    {
        Delimiter = ";",
        Encoding = Encoding.UTF8
    };

    //using (var writer = new StreamWriter("path\to\file.csv"))
    using (var csv = new CsvWriter(Console.Out, config))
    {
        csv.Context.RegisterClassMap<ContractMap>();
        
        csv.WriteRecords(records);
    }
}

class ContractMap : ClassMap<Contract>
{
    public ContractMap()
    {
        Map(x => x.Id);
        Map(x => x.Type);
        Map(x => x.FileNames).Name("FileName").Index(3,5);
    }
}

class Contract
{
    public Contract()
    {
        Id = "None";
        Type = "";
        FileNames = new List<string>();
    }
    public string Id { get; set; }
    public string Type { get; set; }
    public List<String> FileNames { get; set; }
    public override string ToString()
    {
        string result = "Contract:ID " + Id
        + ",Type " + Type
        + ",FileNames ";
        foreach (string FileName in FileNames)
        {
            result = result + FileName + ",";
        }
        return result;
    }
}

user nilsK in a comment 所述,所提出的问题是在编写 header.

后缺少代码 csv.NextRecord();

此外,您似乎也想将文件名写入 CSV 文件。由于 CsvHelper 不会直接为您编写 List<string>,您可以将另一个 属性 添加到它可以编写的 Contract class。

最好用文件名中不会出现的字符分隔文件名,例如 semi-colon.

using CsvHelper;
using CsvHelper.Configuration;
using CsvHelper.TypeConversion;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;

namespace CsvWrite
{

    public class Program
    {
        public class ContractMap : ClassMap<Contract>
        {
            public ContractMap()
            {
                Map(m => m.Id).Index(0).Name("Id");
                Map(m => m.Type).Index(1).Name("Type");
                Map(m => m.FileNames).Index(2).Name("Filenames");
            }
        }

        public class Contract
        {
            public string Id { get; set; }
            public string Type { get; set; }
            public List<String> FileNames { get; set; }
            public string Filenames { get => string.Join(";", FileNames); }

            public Contract()
            {
                Id = "None";
                Type = "";
                FileNames = new List<string>();
            }

            public override string ToString()
            {
                return "Contract:ID " + Id
                + ",Type " + Type
                + ",FileNames " + string.Join(',', FileNames);
            }
        }

        public static void SaveCsv(string PathCsv, List<Contract> contracts)
        {
            Console.WriteLine("Save Contracts to " + PathCsv);

            var config = new CsvConfiguration(CultureInfo.InvariantCulture)
            {
                Delimiter = ";",
                Encoding = Encoding.UTF8
            };
            using (var writer = new StreamWriter(PathCsv))
            using (var csv = new CsvWriter(writer, config))
            {
                csv.WriteRecords(contracts);
            }
        }

        static void Main(string[] args)
        {
            var contracts = new List<Contract>();

            contracts.Add(new Contract { Type = "A", Id = "1"});
            contracts.Add(new Contract { Type = "BB", Id = "100", FileNames = new List<string> { "F1", "F2" } });
            contracts.Add(new Contract { Type = "CCC", Id = "1111", FileNames = new List<string> { "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10" } });

            string f = @"C:\temp\SaveCsv.csv";
            SaveCsv(f, contracts);
        }
    }
}

输出:

Id;Type;Filenames
1;A;
100;BB;"F1;F2"
1111;CCC;"F1;F2;F3;F4;F5;F6;F7;F8;F9;F10"