【问题标题】:How to write a C# List to CSV with CsvHelper package如何使用 CsvHelper 包将 C# 列表写入 CSV
【发布时间】:2020-07-26 07:54:03
【问题描述】:

我有一个简单的控制台应用程序,其中包含 Program.cs 中 3 个用户的列表。在 Program.cs 中,我想调用 FileOperations.cs 中的一个方法。

首先我的Program.cs

using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using CsvHelper;

namespace GimpiesConsoleOOcsvListUI
{
    class Program
    {
        static void Main(string[] args)
        {
            // Create user default instances
            User user0 = new User("Beheer", "beheer@gimpies.nl", "123");
            User user1 = new User("Inkoop", "inkoop@gimpies.nl", "123");
            User user2 = new User("Verkoop", "verkoop@gimpies.nl", "123");

            // List of users (with a list you can add, get and remove items in the list)
            List<User> users = new List<User>();
            users.Add(user0);
            users.Add(user1);
            users.Add(user2);

            // Create login instance
            LoginManager loginMgr = new LoginManager();

            Start:
            // Welcome message
            Console.WriteLine("Welcome to GimpiesTerminal! Choose 1 to login or 2 to register:");

            // Get input from user
            string input = Console.ReadLine();

            bool successfull = false;

            while (!successfull)
            {
                if(input == "1")
                {
                    Console.WriteLine("Enter your username:");
                    string username = Console.ReadLine();
                    Console.WriteLine("Enter your password:");
                    string password = Console.ReadLine();

                    foreach (User user in users)
                    {
                        if (username == user.UserName && password == user.PassWord)
                            {
                                Console.WriteLine("You have successfully logged in !!!");
                                Console.ReadLine();
                                successfull = true;
                            break;  
                            }
                    }
                        if (!successfull)
                            {
                                Console.WriteLine("Your username or password is incorrect, try again !!!");
                            }
                }
                else if (input == "2")
                {
                        // Get user input
                        Console.WriteLine("Enter your username:");
                        string username = Console.ReadLine();

                        Console.WriteLine("Enter your email:");
                        string email = Console.ReadLine();

                        Console.WriteLine("Enter your password:");
                        string password = Console.ReadLine();

                        // Create fresh instance to save input in memory
                        User user = new User(username, email, password);

                        // Adds the user to the excisting list
                        users.Add(user);
                        
                        successfull = true;
                        goto Start;
                }
                else if (input == "3")
                {
                    // Here I want to call the method from FileOperations.cs to write the List here to a CSV file.
                }
                else
                {
                    Console.WriteLine("Try again !!!");
                    break;
                }
            }
            
            // // Loop over stored users within instances inside the list where users are added
            // foreach (User user in users)
            // {
            
            //     if(loginMgr.Login(user))
            //     {
            //         // Login successfull
            //         Console.WriteLine("Login user " + user.UserName);

            //     }
            //     else
            //     {
            //         // Not successfull

            //     }
            // }  
            
        }
    }
}

这是我的FileOperations.cs

using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using CsvHelper;

namespace GimpiesConsoleOOcsvListUI
{
    public class FileOperations
    {
        // Handles CRUD within CSV files and able to save them
        public void SaveToCSV(User user)
        {
            using (var mem = new MemoryStream())
            using (var writer = new StreamWriter(mem))
            using (var csvWriter = new CsvWriter(writer))
            {
                csvWriter.Configuration.Delimiter = ";";
                csvWriter.Configuration.HasHeaderRecord = true;
                csvWriter.Configuration.AutoMap<User>();

                csvWriter.WriteHeader<User>();
                csvWriter.WriteRecords(user);

                writer.Flush();
                var result = Encoding.UTF8.GetString(mem.ToArray());
                Console.WriteLine(result);
            }
        }
    } 
}

我在FileOperations.cs 的第 16 行收到以下错误:

StreamWriter 编写器 参数 1:无法从 System.IO.StreamWriter 转换为 CsvHelper.ISerializer

第 23 行:

用户用户 参数 1:无法从 GimpiesConsoleOOcsvListUI.User 转换为 System.Collections.IEnumerable

我是 C# 的新手,所以我希望你不介意它是否很容易解决问题! :-)

【问题讨论】:

  • 我不明白你的代码流程;您有一个要保存的用户列表,并且您有一个类,该类的方法仅将单个用户保存到内存流中(因此不保存到磁盘中),然后立即将内存流丢弃,因此任何地方都不会保存任何内容。可能值得仔细阅读您的代码并评论算法,以便您拥有一套本地语言的步骤来实现目标,然后您可以评估评论下的 c# 是否真的按照评论所说的那样做; “先用英文(/你的母语思维语言)写,然后翻译成c#”
  • 不要使用goto

标签: c# .net list csv csvhelper


【解决方案1】:

您收到错误是因为您在两种情况下都传递了错误的参数类型。 CsvWriter 没有构造函数,它只接受一个参数是 TextWriter。我对这个库不是很熟悉,但我相信它可能在过去做过。我怀疑您从互联网上的先前示例中复制了您的代码,这些示例已过时。

解决这个问题的简单方法是添加另外两个参数:

using (var csvWriter = new CsvWriter(writer, CultureInfo.CurrentCulture, false))

第二个错误是因为CsvWriter.WriteRecords 需要一个IEnumerable 参数,而不是单个实例。要解决此问题,您需要将List&lt;User&gt; 传递给它,因此整个代码变为:

public void SaveToCSV(List<User> users)
{
    using (var mem = new MemoryStream())
    using (var writer = new StreamWriter(mem))
    using (var csvWriter = new CsvWriter(writer, CultureInfo.CurrentCulture, false))
    {
        csvWriter.Configuration.Delimiter = ";";
                
        csvWriter.Configuration.HasHeaderRecord = true;
        csvWriter.Configuration.AutoMap<User>();

        csvWriter.WriteHeader<User>();
        csvWriter.WriteRecords(users);

        writer.Flush();
        var result = Encoding.UTF8.GetString(mem.ToArray());
        Console.WriteLine(result);
    }
}

【讨论】:

  • 感谢您的示例和解释。 ? 我很快就会试一试。当它起作用时,我会回到这个线程。同样在解决方案之后,我会将其更改为将信息实际保存到 CSV 文件中。
  • Jonathan:多亏了你的例子,我做了一些步骤。也msmolcic谢谢!您的反馈和示例都使它起作用。现在还有一些微调! :-D
【解决方案2】:

如果您想序列化单个用户对象并显示其序列化的标头和值,可以尝试以下代码:

public void SaveToCSV(User user)
{
    using (var writer = new StringWriter())
    using (var csvWriter = new CsvWriter(writer, CultureInfo.InvariantCulture, leaveOpen: true))
    {
        csvWriter.Configuration.Delimiter = ";";
        csvWriter.Configuration.HasHeaderRecord = true;
        csvWriter.Configuration.AutoMap<User>();

        csvWriter.WriteHeader<User>();
        csvWriter.WriteRecord(user);
        csvWriter.Flush();

        var result = writer.ToString();
        Console.WriteLine(result);
    }
}

它使用库的CsvWriter 所需的简单StringWriter 实例,并使用InvariantCulture 信息进行内容序列化。在这种情况下,第三个参数leaveOpen 必须设置为true,因为您对using 块范围内的StringWriter 的内容感兴趣。最后但同样重要的是,您当前正在传递 User 的单个实例,因此您必须调用 WriteRecord 方法而不是 WriteRecords

如果你想将它写入实际文件,你必须做一些不同的事情:

public void SaveToCSV(User user)
{
    using (var writer = new StreamWriter("path\\to\\your\\file.csv"))
    using (var csvWriter = new CsvWriter(writer, CultureInfo.InvariantCulture))
    {
        csvWriter.Configuration.Delimiter = ";";
        csvWriter.Configuration.HasHeaderRecord = true;
        csvWriter.Configuration.AutoMap<User>();

        csvWriter.WriteHeader<User>();
        csvWriter.WriteRecord(user);
    }
}

您不需要在第二个示例中调用 Flush,因为 using 块的末尾会为您调用它,而您对其范围内的 CSV 内容不感兴趣。

【讨论】:

  • 啊,谢谢你的努力。我也会试一试。我的下一步确实是写入 CSV 文件。当我尝试了你所有的建议后,我会回来的。
  • 我尝试编写 csv 文件并且它有效!我现在唯一的问题是列表的第一个条目写在标题项旁边。所以它变成了这样: Name ;电子邮件 ;密码 ;行政 ; admin@admin.com ; 123 销售;销售@admin.com; 123 购买;购买@admin.com; 123也许你知道怎么解决这个问题?
  • 我用一个空的第一个用户做了一个临时解决方案:// Create user default instances User user0 = new User("", "", ""); User user1 = new User("Beheer", "beheer@gimpies.nl", "123"); User user2 = new User("Inkoop", "inkoop@gimpies.nl", "123"); User user3 = new User("Verkoop", "verkoop@gimpies.nl", "123");
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-09
  • 1970-01-01
相关资源
最近更新 更多