如何将对象列表转换为 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;
如何转换对象列表,例如将
【问题讨论】:
你能转换它吗?你试过哪一个? 【参考方案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?的主要内容,如果未能解决你的问题,请参考以下文章