我有一个列表,我想写入CSV字符串.
我发现的例子似乎都是针对单个项目列表,我的有多个项目.
我目前的代码是;
private static string CreateCSVTextFile<T>(List<T> data,string seperator = ",") where T : ExcelReport,new()
{
var objectType = typeof(T);
var properties = objectType.GetProperties();
var currentRow = 0;
var returnString = "";
foreach (var row in data)
{
var currentColumn = 0;
var linestring = "";
foreach (var info in properties)
{
linestring = linestring + info.GetValue(row,null) + seperator;
currentColumn++;
}
if (seperator != "")
{
linestring = linestring.Substring(0,linestring.Count() - 2);
}
returnString = returnString + Environment.NewLine + linestring;
currentRow++;
}
return returnString;
}
但是当列表很大时,此方法需要很长时间才能运行.
我的列表基于外观;
internal class ClientMasterFile
{
public String COL1{ get; set; }
public String COL2{ get; set; }
public String COL3{ get; set; }
public String COL4{ get; set; }
public String COL5{ get; set; }
public String COL6{ get; set; }
public String COL7{ get; set; }
public String COL8{ get; set; }
public String COL9{ get; set; }
public String COL10{ get; set; }
public String COL11{ get; set; }
public String COL12{ get; set; }
}
使用高级版本的String.Join有更快的方法吗?
谢谢
解决方法
使用
StringBuilder和
string.Join可以简化您的方法.
直接连接字符串很慢并且使用大量内存,这对于小型操作来说很好.
见:Does StringBuilder use more memory than String concatenation?
private static string CreateCSVTextFile<T>(List<T> data,")
{
var properties = typeof(T).GetProperties();
var result = new StringBuilder();
foreach (var row in data)
{
var values = properties.Select(p => p.GetValue(row,null));
var line = string.Join(seperator,values);
result.AppendLine(line);
}
return result.ToString();
}
CSV的更完整实现:
private static string CreateCSVTextFile<T>(List<T> data)
{
var properties = typeof(T).GetProperties();
var result = new StringBuilder();
foreach (var row in data)
{
var values = properties.Select(p => p.GetValue(row,null))
.Select(v => StringToCSVCell(Convert.ToString(v)));
var line = string.Join(",",values);
result.AppendLine(line);
}
return result.ToString();
}
private static string StringToCSVCell(string str)
{
bool mustQuote = (str.Contains(",") || str.Contains("\"") || str.Contains("\r") || str.Contains("\n"));
if (mustQuote)
{
StringBuilder sb = new StringBuilder();
sb.Append("\"");
foreach (char nextChar in str)
{
sb.Append(nextChar);
if (nextChar == '"')
sb.Append("\"");
}
sb.Append("\"");
return sb.ToString();
}
return str;
}
使用:escaping tricky string to CSV format