如何将对象列表转换为 csv?

Posted

技术标签:

【中文标题】如何将对象列表转换为 csv?【英文标题】:How can I convert a list of objects to csv? 【发布时间】:2011-01-19 09:13:30 【问题描述】:

如果我有一个名为“汽车”的对象列表:

public class Car

     public string Name;
     public int Year;
     public string Model;

如何转换对象列表,例如将 列出到 csv?

【问题讨论】:

你能转换它吗?你试过哪一个? 【参考方案1】:
    FileHelpers图书馆 文本 OleDb 提供程序 根据RFC-4180手动通过字符串连接 第三方库,例如Aspose.Cells 可以做到这一点,而不会与您产生任何摩擦。而且它非常快。

【讨论】:

+1 表示 RFC 的链接!***上也有很好的参考:en.wikipedia.org/wiki/Comma-separated_values【参考方案2】:

将以下方法添加到 Car:

String Escape(String s)

    StringBuilder sb = new StringBuilder();
    bool needQuotes = false;
    foreach (char c in s.ToArray())
    
        switch (c)
        
            case '"': sb.Append("\\\""); needQuotes = true; break;
            case ' ': sb.Append(" "); needQuotes = true; break;
            case ',': sb.Append(","); needQuotes = true; break;
            case '\t': sb.Append("\\t"); needQuotes = true; break;
            case '\n': sb.Append("\\n"); needQuotes = true; break;
            default: sb.Append(c); break;
        
    
    if (needQuotes)
        return "\"" + sb.ToString() + "\"";
    else
        return sb.ToString();


public void SerializeAsCsv(Stream stream)

    stream.Write(Escape(Name));
    stream.Write(",");
    stream.Write(Year.ToString());
    stream.Write(",");
    stream.Write(Escape(Model));
    stream.Write("\n");

现在你可以序列化整个列表了:

foreach (Car car in list)

    car.SerializeAsCsv(stream);

【讨论】:

【参考方案3】:

查看FileHelpers 库。

来自网站:

The FileHelpers are a free and easy to use .NET library to import/export data from fixed length or delimited records in files, strings or streams.

这将确保按照RFC-4180 正确处理行终止、转义等中的各种陷阱。

【讨论】:

【参考方案4】:

我正在为此寻找解决方案,但我找到的答案都没有满足我对简单性的追求。我意识到我已经用我的自动 CRUD 代码找到了答案。我重新调整了它的用途并提出了以下代码:

using System.Reflection;
    /// <summary>
    /// Using a bit of reflection to build up the strings.
    /// </summary>
    public static string ToCsvHeader(this object obj)
    
        Type type = obj.GetType();
        var properties = type.GetProperties(BindingFlags.DeclaredOnly |
                                       BindingFlags.Public |
                                       BindingFlags.Instance);

        string result = string.Empty;
        Array.ForEach(properties, prop =>
        
            result += prop.Name + ",";
        );

        return (!string.IsNullOrEmpty(result) ? result.Substring(0, result.Length - 1) : result);
    

    public static string ToCsvRow(this object obj)
    
        Type type = obj.GetType();
        var properties = type.GetProperties(BindingFlags.DeclaredOnly |
                                       BindingFlags.Public |
                                       BindingFlags.Instance);

        string result = string.Empty;
        Array.ForEach(properties, prop =>
        
            var value = prop.GetValue(obj, null);
            var propertyType = prop.PropertyType.FullName;
            if (propertyType == "System.String")
            
                // wrap value incase of commas
                value = "\"" + value + "\"";
            

            result += value + ",";

        );

        return (!string.IsNullOrEmpty(result) ? result.Substring(0, result.Length - 1) : result);
    

这将为每个对象添加一个扩展方法。用法如下:

var burgers = new List<Cheeseburger>();
var output = burgers.ToCsvHeader();
output += Environment.NewLine;

burgers.ForEach(burger =>

    output += burger.ToCsvRow();
    output += Environment.NewLine;
);
var path = "[where ever you want]";
System.IO.File.WriteAllText(path, output);

上面可能有更好的方法来编写这两种方法,但这非常适合我的情况。希望它可以帮助某人。

【讨论】:

【参考方案5】:

您可以简单地覆盖 ToString 方法或创建一个 ToCSVRow() 方法

    public String ToCSVRow()
    
        return Name + "," + Year.ToString() + "," + Model;
    

然后在需要的地方做这样的事情。

    using (StreamWriter file = new StreamWriter(@"C:\Wherever\yourfilename.txt"))
        
            foreach (var item in yourlist)
            
                file.WriteLine(item.ToCSVRow());
            
        

【讨论】:

【参考方案6】:

将逗号分隔的值放在一起我总是喜欢指出被低估的string.Join(string separator, string[] elements) 静态方法,但如果有帮助库,那可能是更好的东西。

【讨论】:

【参考方案7】:

我会根据article 实现一些额外的序列化行为。如果你想变得花哨,你可以在你的项目属性中创建一个设置。此设置将确定您的类是使用 csv 还是默认序列化。然后,您将通过here 显示的技术访问它。考虑使用静态构造函数来读取 appsettings 并使您的序列化代码可以访问布尔值。 Vlads 的代码看起来很棒,只需将其插入您的代码即可。您还可以考虑其他可能更理想的方法来改变您的序列化行为。

或者创建一个名为“SerializeAsCSV”的接口并像这样使用它:

// MyCoolClass.csv的部分内容:

   public class MyCoolClass : ISerializeAsCSV, IDisposable
   

      protected static bool serializesToCSV = false;


      static MyCoolClass()
      
         serializesToCSV = 
            (typeof(MyCoolClass).GetInterface("GrooveySoft.Shared.Interfaces.ISerializeAsCSV") == null)
            ? false
            : true;

      


      public MyCoolClass(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context)
      
        // your stuff here
      

      public void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context)
      
         // your stuff here
      

    

// ISerializeAsCSV.cs 的内容

using System.Runtime.Serialization;

namespace GrooveySoft.Shared.Interfaces

   /// <summary>
   /// indicates that implementor will serialize to csv format
   /// </summary>
   public interface ISerializeAsCSV : ISerializable
   
   

这应该让你开始。 . .我还没有编译和测试这个。 .但你明白了。

【讨论】:

【参考方案8】:

另一个选项是Linq to CSV,它是 NuGet 提供的一个包。用法见Combine contents of two files using LINQ to CSV。

【讨论】:

以上是关于如何将对象列表转换为 csv?的主要内容,如果未能解决你的问题,请参考以下文章

将列表转换为 csv 格式时如何修复编码错误?

如何将此字典列表转换为 csv 文件?

如何将 csv 文件转换为可作为文本读取的列表列表? Python

如何将列表转换为每行 N 项的 CSV 文件?

如何将 csv 字符串转换为 pandas 中的列表?

如何将 csv 字符串转换为 pandas 中的列表?