Добавление двойных кавычек в строку при записи в csv с #

Я пытаюсь записать данные в файл csv. Я хочу, чтобы данные отображались в двойных кавычках при открытии в блокноте, но они не должны отображать двойные кавычки, когда я открываю файл в csv.

Ниже приведен код, который я использую, но он не дает результата.

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

Может ли кто-нибудь мне с этим помочь?


person user2083386    schedule 18.06.2020    source источник
comment
Похоже, есть опция конфигурации и переопределение для WriteField для принудительного цитирования. Воспользуйтесь одним из них.   -  person Retired Ninja    schedule 19.06.2020
comment
Есть много других ответов (например, этот) о том, как преобразовать кавычки в строки. Но я думаю, ваша проблема в том, как вы используете тернарный оператор a ? b : c. Попробуйте заключить его в круглые скобки, например: "\"" + (data.FirstName == null ? string.Empty : data.FirstName) + "\"". Порядок операций, вероятно, проверяет "\"" + data.Firstname == null, чего никогда не бывает, потому что в результирующей строке всегда есть как минимум двойные кавычки.   -  person Sean Skelly    schedule 19.06.2020


Ответы (2)


Проблема в том, что вы пытаетесь бороться с цитированием CsvHelper. Согласно спецификациям RFC 4180.

  1. Поля, содержащие разрывы строк (CRLF), двойные кавычки и запятые, должны быть заключены в двойные кавычки. Например:
       "aaa","b CRLF
       bb","ccc" CRLF
       zzz,yyy,xxx
  1. Если для заключения полей используются двойные кавычки, то двойные кавычки внутри поля должны быть экранированы, поставив перед ними другую двойную кавычку. Например:
       "aaa","b""bb","ccc"

Поэтому, когда вы добавляете в поле двойные кавычки, CsvHelper распознает, что все поле должно быть заключено в двойные кавычки, а добавленные кавычки должны быть экранированы другой двойной кавычкой. Вот почему у вас получается 3 двойные кавычки.

CsvHelper имеет функцию конфигурации, с помощью которой вы можете указать, когда следует указать поле в кавычках. У @JoshClose уже есть ответ здесь для заключения всех полей в двойные кавычки. Я обновлю его для текущей версии 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 и новее

изменен CsvConfiguration на запись только для чтения, чтобы устранить проблемы с потоками.

Вам нужно будет создать 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; }
}
person David Specht    schedule 19.06.2020
comment
Большое спасибо. В моем случае у меня работала следующая строка csv.Configuration.ShouldQuote = (field, context) = ›true; - person user2083386; 22.06.2020
comment
Это дает мне следующую ошибку: Property or indexer 'IWriterConfiguration.ShouldQuote' cannot be assigned to -- it is read only - person agileMike; 04.05.2021
comment
В версии 20.0.0 произошло критическое изменение. Добавил обновление с изменениями. - person David Specht; 06.05.2021

Я сделал код более читабельным, присвоив переменной firstName значение, которое будет передано позже. Я использовал escape-строку, чтобы добавить кавычку к окончательному результату. Теперь вы можете передать его своему методу WriteField.

Дополнительную информацию об экранировании строки можно найти: здесь и здесь.

var firstName = data.FirstName == null ? string.Empty : data.FirstName;
var firstNameWithQuoutes = $@"""{firstName}""";
person kyziur    schedule 18.06.2020
comment
Спасибо за ваш ответ. Я попробовал ваше решение, но оно все равно не сработало. Я получаю результат в блокноте как тест, который имеет 3 двойные кавычки, а в файле csv он отображается как тест для имени - person user2083386; 19.06.2020