CSV export 函数,字符串中包含字符分隔符怎么办?

CSV export Function, what to do if string contains the character seperator?

我使用函数将数据table 转换为 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 中,分隔符是“;”。现在,当 table 中的字符串包含分号时,当然会发生错误。是否有解决问题的优雅方法?

我写了一个小帮手来格式化我的 CSV 的每一行。

private string FormatForCsv(string value) => value != null && value.Contains(';') ? value.Replace(value, "\"" + value + "\"") : value;

那么你可以使用:

sb.Append(FormatForCsv(dr[i]?.ToString()));

当然你也可以对headers使用同样的方法。

为了安全起见,我在将 dr[i] 转换为字符串时还添加了空检查。

您应该考虑使用库来为您处理 CSV 部分。当前接受的答案在值包含定界符时处理引号,但是当值包含引号字符或以引号字符开头时会发生什么,或者如果值包含换行符怎么办?该方法将创建一个无效文件。事实上 CSV standard 指定当值包含定界符或换行符时应引用字段,并且引号应加倍以“转义”它们。

有很多库可以帮助解决这个问题,包括我的作者之一:Sylvan.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();
}