我有一个课程如下:
public class Test
{
public int Id {get;set;}
public string Name { get; set; }
public string CreatedDate {get;set;}
public string DueDate { get; set; }
public string ReferenceNo { get; set; }
public string Parent { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我有一个Test对象列表
List<Test>testobjs=new List();
Run Code Online (Sandbox Code Playgroud)
现在我想以下列格式将其转换为csv:
"1,约翰格里沙姆,9/5/2014,9/5/2014,1356,0\N 2,斯蒂芬金,9/3/2014,9/9/2014,1367,0\N3,造雨,4/9/2014,18/9/2014,1" ;
我搜索了"将列表转换为csv c#",我得到的解决方案如下:
string.Join(",", list.Select(n => n.ToString()).ToArray())
Run Code Online (Sandbox Code Playgroud)
但是这不会根据需要放置\n,即每个对象
除了字符串构建之外还有其他最快的方法吗?请帮忙...
unr*_*eal 36
使用servicestack.text
Install-Package ServiceStack.Text
Run Code Online (Sandbox Code Playgroud)
然后使用字符串扩展方法 ToCsv(T)/FromCsv()
示例:https: //github.com/ServiceStack/ServiceStack.Text
更新:
Servicestack.Text
现在也是免费的v4曾经是商业版.无需再指定版本!快乐连载!
更新:ToCsv(T)/FromCsv()
用于.NET Core.
小智 14
If you don't want to load library's than you can create the following method:
private void SaveToCsv<T>(List<T> reportData, string path)
{
var lines = new List<string>();
IEnumerable<PropertyDescriptor> props = TypeDescriptor.GetProperties(typeof(T)).OfType<PropertyDescriptor>();
var header = string.Join(",", props.ToList().Select(x => x.Name));
lines.Add(header);
var valueLines = reportData.Select(row => string.Join(",", header.Split(',').Select(a => row.GetType().GetProperty(a).GetValue(row, null))));
lines.AddRange(valueLines);
File.WriteAllLines(path, lines.ToArray());
}
Run Code Online (Sandbox Code Playgroud)
and than call the method:
SaveToCsv(testobjs, "C:/PathYouLike/FileYouLike.csv")
Run Code Online (Sandbox Code Playgroud)
小智 13
因为在问题中提到了速度,我的兴趣被激发了相对表现可能是什么,以及我能够多快地得到它.
我知道StringBuilder被排除在外,但它仍然感觉可能是最快的,而StreamWriter当然具有写入MemoryStream或直接写入文件的优势,这使得它具有多种功能.
所以我敲了一个快速测试.
我建立了一个与你的相同的五十万个物品清单.
然后我使用CsvSerializer序列化,并使用两个手动滚动的紧密版本,一个使用StreamWriter到MemoryStream,另一个使用StringBuilder.
手动编码被编码以应对引号,但没有更复杂.这个代码非常紧凑,我可以管理中间字符串,没有连接...但不是生产,当然没有样式或灵活性的点.
但是在所有三种方法中输出都是相同的.
时间很有趣:
序列化50万个对象,每个方法运行5次,所有时间都到最近的整个mS:
StringBuilder 703 734 828 671 718 Avge= 730.8
MemoryStream 812 937 874 890 906 Avge= 883.8
CsvSerializer 1,734 1,469 1,719 1,593 1,578 Avge= 1,618.6
Run Code Online (Sandbox Code Playgroud)
这是一个高端的i7,有足够的RAM.
在其他条件相同的情况下,我总是会使用这个库.
但是,如果2:1的性能差异变得至关重要,或者RAM或其他问题变得夸大了较大数据集的差异,或者数据是以块的形式到达并且要直接发送到磁盘,我可能会受到诱惑...
为了防止任何人感兴趣,代码的核心(对于StringBuilder版本)是
private void writeProperty(StringBuilder sb, string value, bool first, bool last)
{
if (! value.Contains('\"'))
{
if (!first)
sb.Append(',');
sb.Append(value);
if (last)
sb.AppendLine();
}
else
{
if (!first)
sb.Append(",\"");
else
sb.Append('\"');
sb.Append(value.Replace("\"", "\"\""));
if (last)
sb.AppendLine("\"");
else
sb.Append('\"');
}
}
private void writeItem(StringBuilder sb, Test item)
{
writeProperty(sb, item.Id.ToString(), true, false);
writeProperty(sb, item.Name, false, false);
writeProperty(sb, item.CreatedDate, false, false);
writeProperty(sb, item.DueDate, false, false);
writeProperty(sb, item.ReferenceNo, false, false);
writeProperty(sb, item.Parent, false, true);
}
Run Code Online (Sandbox Code Playgroud)
您最好的选择是使用现有的库。它为您省去了自己弄清楚的麻烦,并且可能会处理转义特殊字符、添加标题行等。您可以使用ServiceStack 中的CSVSerializer。但是nuget中还有其他几个。创建 CSV 将变得如此简单string csv = CsvSerializer.SerializeToCsv(testobjs);