使用 CsvHelper 读取 CSV 文件

Reading a CSV file using CsvHelper

我是新手。我想从 CSV 文件中获取数据——Id 和 Name 字段,但是当我 运行 读取方法时,我只得到 100 行不可理解的类型:“CsvHelper.CsvReaderd__87`1[Program +产品]”。我不知道如何从CSV中获取数据,我也无法理解错误在哪里。

虽然文档说属性和CSV header的名称相同,但是你不需要写额外的配置。但是,我得到了上面指定的结果。 CSV 名称与 类 匹配。 Link 到文档:https://joshclose.github.io/CsvHelper/getting-started/

阅读方法:

  {
        using (var reader = new StreamReader("C:\Users\Saint\Desktop\TaskRetail\file.csv", Encoding.UTF8))
        using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
        {
            var records = csv.GetRecords<Product>();
            Console.WriteLine($"{records}");
        }
    }

CSV 创建没有问题,有两列 Id 和 Name 填充行,总共有 100 行:

使用 Id 和 Name 字段创建 csv 的方法:

   using (var writer = new StreamWriter("C:\Users\Saint\Desktop\TaskRetail\file.csv", false, Encoding.UTF8))
    using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
    {
        csv.WriteRecords(products);
    }

完整代码:

using CsvHelper;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Net;
using System.Text;
using System.Xml;

public class Program
{

    public class Product
    {
        public int Id { get; set; }
        public string Name { get; set; }

        public Product(int id, string name)
        {
            Id = id;
            Name = name;
        }
    }
    public const string PathToDoc = "C:/Users/Saint/Desktop/TaskRetail/yml.xml";


    public static void Main(string[] args)
    {
        string url = "https://www.googleapis.com/drive/v3/files/1sSR9kWifwjIP5qFWcyxGCxN0-MoEd_oo?alt=media&key=AIzaSyBsW_sj1GCItGBK0vl8hr9zu1I1vTI1Meo";
        string savePath = @"C:\Users\Saint\Desktop\TaskRetail\yml.xml";
        WebClient client = new WebClient();
        client.DownloadFile(url, savePath);

        Research();
    }

    public static void Research()
    {
        Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);

        var document = new XmlDocument();
        document.Load(PathToDoc);
        var xmlDoc = document.SelectNodes("/yml_catalog/shop/offers/offer");
        var count = xmlDoc.Count;
        var products = new List<Product>();
        Console.WriteLine($"Offers count: {count}");
        for (var i = 0; i < count; i++)
        {
            var element = xmlDoc.Item(i);
            var id = int.Parse(element.Attributes.GetNamedItem("id").Value);
            var name = element.SelectSingleNode("name").InnerText;
            var product = new Product(id, name);
            //Console.WriteLine($"Id: {id}, name: {name}");

            products.Add(product);

            using (var writer = new StreamWriter("C:\Users\Saint\Desktop\TaskRetail\file.csv", false, Encoding.UTF8))
            using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
            {
                csv.WriteRecords(products);
            }

         var config = new CsvConfiguration(CultureInfo.InvariantCulture) { Delimiter = ",", PrepareHeaderForMatch = header => header.Header.ToLower() };
        using (var reader = new StreamReader("C:\Users\Saint\Desktop\TaskRetail\file.csv", Encoding.UTF8))
        using (var csv = new CsvReader(reader, config))

        {
            var records = csv.GetRecords<Product>();

            foreach (var record in records)
            {
                Console.WriteLine($"{record.Id} {record.Name}");
            }
        }
    }
}

}

因为 GetRecords() 做 return 类型 IEnumerable 的 object, 你必须遍历你的记录来打印每一个:

foreach(var record in records)
{
   Console.WriteLine($"{record.Id} {record.Name}");
}

此外,您必须访问要单独打印的每个 属性。 另一种选择是覆盖 Product class.

中的 ToString() 方法

编辑

最初的问题不是值的正确打印,而是文件的解析,正如我从这条评论中了解到的那样:

CsvHelper.HeaderValidationException: 'Header with name 'id'[0] was not found. Header with name 'name'[0] was not found.

要解决这个问题,必须确保分隔符设置正确。这可以在 CsvHelper 的配置 object 中强制执行。此外,为了避免大小写错误,可以将配置设置为忽略 headers:

的大小写
var config = new CsvConfiguration(CultureInfo.InvariantCulture) 
{ 
   Delimiter = ",", // Enforce ',' as delimiter
   PrepareHeaderForMatch = header => header.Header.ToLower() // Ignore casing
};

using (var csv = new CsvReader(reader, config))
{
   ...
}