如何解决使用 CsvHelper 读取 CSV 文件
我是新手。我想从 CSV 文件中获取数据——Id 和 Name 字段,但是当我运行读取方法时,我只得到了 100 行难以理解的类型:“CsvHelper.CsvReaderd__87`1[Program+Product]”。我不知道如何从 CSV 中获取数据,我也无法理解错误在哪里。
虽然文档说属性和 CSV 标头具有相同的名称,但您不需要编写额外的配置。但是,我得到了上面指定的结果。 CSV 名称与类匹配。文档链接: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",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",config))
{
var records = csv.GetRecords<Product>();
foreach (var record in records)
{
Console.WriteLine($"{record.Id} {record.Name}");
}
}
}
}
}
解决方法
因为 GetRecords()
确实返回了 IEnumerable
类型的对象,
你必须遍历你的记录来打印每一个:
foreach(var record in records)
{
Console.WriteLine($"{record.Id} {record.Name}");
}
此外,您必须访问要单独打印的每个属性。
另一种选择是覆盖 ToString()
类中的 Product
方法。
编辑
最初的问题不是值的正确打印,而是我从这条评论中了解到的文件解析:
CsvHelper.HeaderValidationException: '找不到名称为 'id'[0] 的标题。未找到名为“name”[0] 的标题。
要解决这个问题,必须确保正确设置了分隔符。这可以在 CsvHelper 的配置对象中强制执行。此外,为了避免大小写错误,可以将配置设置为忽略标题的大小写:
var config = new CsvConfiguration(CultureInfo.InvariantCulture)
{
Delimiter = ",",// Enforce ',' as delimiter
PrepareHeaderForMatch = header => header.Header.ToLower() // Ignore casing
};
using (var csv = new CsvReader(reader,config))
{
...
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。