ハロの外部記憶インターフェイス

そろそろ覚える努力が必要かも…

CsvHelperで出力にダブルクォーテーションをつける

概要

CsvHelperでcsv出力でダブルクォーテーションを設定しようとして、かなり苦労したのでメモっておく
検索してみると「CsvWriter.Configuration.QuoteAllFields」をTrueにするSampleばかり出てきたけど、CsvHelper Ver12にはこのプロパティは存在しなかった。
プロパティで検索してみたら「Configuration.ShouldQuote」を使えと作者からの回答が見つかったため、解決した。

Configuration.ShouldQuote 使ってダブルクォーテーションを出力する

using (StreamWriter sw = new StreamWriter(File.Create(_outFilePath), utf8_Bom))
{
    using (var writer = new CsvHelper.CsvWriter(sw))
    {
        //writer.Configuration.QuoteAllFields = true;
        writer.Configuration.ShouldQuote = (field, context) => true;
        writer.WriteRecords<GeocodingOutput>(output);
    }
}

CustomConverterを使ってみる

ShouldQuoteでは全カラムに適用されるため、任意の項目にだけ適用する場合は、TypeConverterでMapしないと行けないらしい。
とりあえず、サンプルになりそうな部分だけメモ
ClassMapで各出力項目毎にConverterを指定して、出力内容をカスタムできる

public class CsvOutput
{
  public string a { get; set; }
  public string b { get; set; }
}

// ClassMap
public class CsvOutputMap : CsvHelper.Configuration.ClassMap<CsvOutput>
{
  public CsvOutputMap()
  {
    Map( x => x.a).TypeConverter(new CsvDoubleQuoteConverter);
    Map( x => x.b).TypeConverter(new CsvNonDoubleQuoteConverter);
  }
}

// Converter
public class CsvDoubleQuoteConverter : CsvHelper.TypeConversion.StringConverter
{
 public override string ConvertToString(object value, IWriterRow row, MemberMapData memberMapData)
 {
    row.Configuration.ShouldQuote = (field, context) => true;
    string ret = base.ConvertToString(value, row, memberMapData);
    row.Configuration.ShouldQuote = (field, context) => false;
   return ret;
 }
}
public class CsvNonDoubleQuoteConverter : CsvHelper.TypeConversion.StringConverter
{
 public override string ConvertToString(object value, IWriterRow row, MemberMapData memberMapData)
 {
    string ret = base.ConvertToString(value, row, memberMapData);
   return ret;
 }
}

using (StreamWriter sw = new StreamWriter(File.Create(_outFilePath), utf8_Bom))
{
    using (var writer = new CsvHelper.CsvWriter(sw))
    {
        writer.Configuration.RegisterClassMap(new CsvOutputMap());
        writer.WriteRecords<GeocodingOutput>(output);
    }
}

参考

https://github.com/JoshClose/CsvHelper/issues/1180 https://teratail.com/questions/97817