首页 > 解决方案 > 如何正确地将 CSV 数据放入 C# 中的自定义类记录中?

问题描述

我想将来自简单 csv 文件的数据放入包含定制类的记录中。这是我的代码:

using System;
using CsvHelper;
using System.IO;    // for accessing the files
using System.Globalization;
using System.Linq;  // to call a list enumerable
using CsvHelper.Configuration;
using CsvHelper.Configuration.Attributes;

namespace Reading_CSV_Files
{
    class Program
    {
        static void Main(string[] args)
        {
            ReadCSVFile(@"C:\path_to_my_file\file.csv");
            
        }



    public static void ReadCSVFile(String filePath)
        {
            if (filePath == null)
            {
                return;
            }

            using (var streamReader = new StreamReader(filePath) )
            {
                using (var foodFileCSVReader = new CsvReader(streamReader, 
                    CultureInfo.InvariantCulture))
                {
                    //var records = foodFileCSVReader.GetRecords<dynamic>().ToList();
                    var records = foodFileCSVReader.GetRecords<Pizza>().ToList();
                    // replace dynamic type argument on our records

                }
            }
        }
    }

    public class Pizza 
    {
        // attributes
        [Name("Name")]
        public String Name { get; set; }

        [Name("PLN_Cost")]
        public double Price { get; set; }
    }
}

csv 文件如下所示: 来自 csv 文件的屏幕截图 该文件以逗号分隔保存。我发现了一些手动设置的建议,但目前它说,这个字段是只读的。

CsvHelper.HeaderValidationException:找不到名称为“名称”[0] 的标头。找不到名为“PLN_Cost”[0] 的标头。

标签: c#csvrecord

解决方案


如果程序将使用可能有逗号或分号作为分隔符的 CSV 文件,您可以读取第一行并将分隔符设置为其中任何一个,如下所示:

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

namespace ConsoleApp1
{
    class Program
    {

        public class Pizza
        {
            // attributes
            [Name("Name")]
            public String Name { get; set; }

            [Name("PLN_Cost")]
            public decimal Price { get; set; }

            public override string ToString()
            {
                return $"{Name} - {Price}";
            }
        }

        public static List<Pizza> ReadCSVFile(String filePath)
        {
            if (!File.Exists(filePath))
            {
                return new List<Pizza>();
            }

            var sep = ";";

            /* Check the header for the separator character to use. */
            string headerLine = File.ReadLines(filePath).First();
            if (headerLine?.IndexOf(',') >= 0) { sep = ","; }

            using (var sr = new StreamReader(filePath))
            {
                var config = new CsvConfiguration(CultureInfo.CurrentCulture)
                {
                    Delimiter = sep,
                    Encoding = Encoding.UTF8
                };

                using (var foodFileCSVReader = new CsvReader(sr, config))
                {
                    return foodFileCSVReader.GetRecords<Pizza>().ToList();

                }
            }
        }

        static void Main(string[] args)
        {
            var pp = ReadCSVFile(@"C:\temp\PizzaPrices.csv");
            Console.WriteLine(string.Join("\r\n", pp));
            Console.ReadLine();
        }

    }

}

请注意,最好使用decimal类型而不是double类型。

您可能需要额外的代码来设置要使用的小数分隔符。


推荐阅读