我使用函数将Datatable转换为CSV,我使用File。WriteAllText保存到文件
private static string DataTableToCSV(DataTable dtable, char seperator)
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < dtable.Columns.Count; i++)
{
sb.Append(dtable.Columns[i]);
if (i < dtable.Columns.Count - 1)
sb.Append(seperator);
}
sb.AppendLine();
foreach (DataRow dr in dtable.Rows)
{
for (int i = 0; i < dtable.Columns.Count; i++)
{
sb.Append(dr[i].ToString());
if (i < dtable.Columns.Count - 1)
{
sb.Append(seperator);
}
}
sb.AppendLine();
}
return sb.ToString();
}
代码是有效的。我的问题是,在CSV分隔符是';'。当然,当表中的字符串包含分号时就会出现错误。也许有一个优雅的方法来解决这个问题?
您应该考虑使用库来处理CSV部分。当值包含分隔符时,当前接受的回答处理引号,但是当值包含引号字符或以引号字符开头时,或者如果值包含换行符会发生什么?这种方法将创建一个无效的文件。事实上的CSV标准规定,当值包含分隔符或换行符时,字段应该加引号,并且引号应该加倍到"escape"他们。
有许多库可以帮助实现这一点,包括我编写的一个库:sylvane . data . csv。Sylvan以一种非常直接的方式处理你的场景:using Sylvan.Data.Csv;
static string DataTableToCSV(DataTable dtable, char seperator)
{
using var sw = new StringWriter();
var opts = new CsvDataWriterOptions { Delimiter = seperator };
using var csvw = CsvDataWriter.Create(sw, opts);
csvw.Write(dtable.CreateDataReader());
return sw.ToString();
}
我编写了一个小助手来格式化CSV文件的每一行。
private string FormatForCsv(string value) => value != null && value.Contains(';') ? value.Replace(value, """ + value + """) : value;
那么你可以使用:
sb.Append(FormatForCsv(dr[i]?.ToString()));
当然,你也可以对标题使用同样的方法。
我还在将dr[i]
转换为字符串时添加了空检查,只是为了安全起见。