在写入csv c#时向字符串添加双引号

Posted

技术标签:

【中文标题】在写入csv c#时向字符串添加双引号【英文标题】:Adding double quotes to string while writing to csv c# 【发布时间】:2020-10-09 02:59:06 【问题描述】:

我正在尝试将数据写入 csv 文件。我希望数据在记事本中打开时以双引号显示,但在 csv 中打开文件时不应显示任何双引号。

以下是我正在使用的代码,但它没有给出结果。

csvFile.WriteField("\"" +data.FirstName == null ? string.Empty : data.FirstName + "\"");

有人可以帮我解决这个问题吗?

【问题讨论】:

看起来有一个配置选项和 WriteField 的覆盖以强制引用。使用其中之一。 还有很多其他答案(如this one)谈论如何将引号转换为字符串。但我认为你的问题是你如何使用三元运算符a ? b : c。尝试在其周围添加括号,例如:"\"" + (data.FirstName == null ? string.Empty : data.FirstName) + "\""。操作顺序可能会检查是否"\"" + data.Firstname == null,它从来都不是,因为结果字符串总是至少有一个双引号。 【参考方案1】:

问题是你试图对抗 CsvHelper 的引用。根据RFC 4180 规范。

    包含换行符 (CRLF)、双引号和逗号的字段 应该用双引号括起来。例如:
       "aaa","b CRLF
       bb","ccc" CRLF
       zzz,yyy,xxx
    如果使用双引号将字段括起来,则使用双引号 出现在字段内必须通过在它前面加上 另一个双引号。例如:
       "aaa","b""bb","ccc"

所以当你在字段中添加双引号时,CsvHelper 会识别出整个字段需要用双引号括起来,并且添加的引号需要用另一个双引号进行转义。这就是为什么你最终会使用 3 个双引号。

CsvHelper 有一个配置函数,你可以告诉它何时应该引用一个字段。 @JoshClose 已经有一个答案 here 用于将所有字段括在双引号中。我会为当前版本的 CsvHelper 更新它。

void Main()

    var records = new List<Foo>
    
        new Foo  Id = 1, Name = "one" ,
        new Foo  Id = 2, Name = "two" ,
    ;

    using (var writer = new StringWriter())
    using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
    
        csv.Configuration.ShouldQuote = (field, context) => true;
        csv.WriteRecords(records);

        writer.ToString().Dump();
    


public class Foo

    public int Id  get; set; 
    public string Name  get; set; 

如果您仍想自己添加双引号,可以关闭 CsvHelper 的双引号。

csv.Configuration.ShouldQuote = (field, context) => false;

20.0.0 及更高版本的重大更改

Changed CsvConfiguration to a read only record to eliminate threading issues.

您需要创建CsvConfiguration,在初始化时设置ShouldQuote,然后将其传递给CsvWriter

void Main()

    var records = new List<Foo>
    
        new Foo  Id = 1, Name = "one" ,
        new Foo  Id = 2, Name = "two" ,
    ;
    
    var config = new CsvConfiguration(CultureInfo.InvariantCulture)
    
        ShouldQuote = (field, context) => true
    ;

    using (var writer = new StringWriter())
    using (var csv = new CsvWriter(writer, config))
    
        csv.WriteRecords(records);

        writer.ToString().Dump();
    


public class Foo

    public int Id  get; set; 
    public string Name  get; set; 

【讨论】:

非常感谢。在我的情况下,以下行对我有用 "csv.Configuration.ShouldQuote = (field, context) => true;" 这给了我以下错误:Property or indexer 'IWriterConfiguration.ShouldQuote' cannot be assigned to -- it is read only 版本 20.0.0 发生了重大变化。我添加了有关更改的更新。【参考方案2】:

通过将 firstName 赋值给稍后将传递的变量,我使代码更具可读性。我使用字符串转义来为最终结果添加引号。现在您可以将它传递给您的 WriteField 方法。

有关字符串转义的更多信息,请参见:here 和 here。

var firstName = data.FirstName == null ? string.Empty : data.FirstName;
var firstNameWithQuoutes = $@"""firstName""";

【讨论】:

感谢您的回复。我尝试了您的解决方案,但仍然没有用。我在记事本中得到的结果是“”“test”“”,它有 3 个双引号,在 csv 文件中,它显示为名字的“test”

以上是关于在写入csv c#时向字符串添加双引号的主要内容,如果未能解决你的问题,请参考以下文章

在c#中写入文件时如何用变量显示双引号? [复制]

使用 c# 在 CSV 文件中用双引号将每个字段括起来

将字符串写入 CSV 时转义逗号

CSV 解析包含双引号和逗号的字符串

停止访问将两组双引号写入 csv

从UTF-8转换为ISO-8859-15时会自动替换哪些双引号字符?