備忘録

備忘録

C#でCsvHelperを使ってCSVを読み込み、書き込みを行う方法

Ⅰ. はじめに

タイトルの通り「C#でCsvHelperを使ってCSVを読み込み、書き込みを行う方法」です。

Ⅱ. インストール

Install-Package CsvHelper

Ⅲ. 読み込む方法

1. CSVにヘッダが有る場合

accounts.csv

Id,Name,CreatedAt
1,田中001,2018/01/01 01:00
2,田中002,2018/01/02 02:00
3,田中003,2018/01/03

Program.cs

class Account
{
  public int Id { get; set; }
  public string Name { get; set; }
  public DateTime CreatedAt { get; set; }
}

class Program
{
  static void Main(string[] args)
  {
    var config = new CsvConfiguration(CultureInfo.GetCultureInfo("ja-jp"))
    {
      Encoding = Encoding.UTF8
    };

    using var csv = new CsvReader(File.OpenText("accounts.csv"), config);
    var accounts = csv.GetRecords<Account>();
    foreach (var x in accounts)
    {
      Console.WriteLine($"{x.Id}, {x.Name}, {x.CreatedAt}");
    }
  }
}
出力

f:id:kagasu:20180529133205p:plain

2. CSVにヘッダが無い場合

accounts.csv

1,田中001,2018/01/01 01:00
2,田中002,2018/01/02 02:00
3,田中003,2018/01/03

Program.cs

class Account
{
  public int Id { get; set; }
  public string Name { get; set; }
  public DateTime CreatedAt { get; set; }
}

class Program
{
  static void Main(string[] args)
  {
    var config = new CsvConfiguration(CultureInfo.GetCultureInfo("ja-jp"))
    {
      Encoding = Encoding.UTF8,
      HasHeaderRecord = false
    };

    using var csv = new CsvReader(File.OpenText("accounts.csv"), config);
    var accounts = csv.GetRecords<Account>();
    foreach (var x in accounts)
    {
      Console.WriteLine($"{x.Id}, {x.Name}, {x.CreatedAt}");
    }
  }
}
出力

f:id:kagasu:20180529133205p:plain

3. 自分でマップを作成する方法

accounts.csv

id,name,created_at
1,田中001,2018/01/01 01:00
2,田中002,2018/01/02 02:00
3,田中003,2018/01/03

Program.cs

class Account
{
  [Name("id")]
  // [Index(0)] /* indexでも指定可 */
  public int Id { get; set; }

  [Name("name")]
  public string Name { get; set; }

  [Name("created_at")]
  public DateTime CreatedAt { get; set; }
}

class Program
{
  static void Main(string[] args)
  {
    var config = new CsvConfiguration(CultureInfo.GetCultureInfo("ja-jp"))
    {
      Encoding = Encoding.UTF8
    };

    using var csv = new CsvReader(File.OpenText("accounts.csv"), config);
    var accounts = csv.GetRecords<Account>();
    foreach (var x in accounts)
    {
      Console.WriteLine($"{x.Id}, {x.Name}, {x.CreatedAt}");
    }
  }
}
出力

f:id:kagasu:20180529133205p:plain

Ⅳ. 書き込む方法

Progrsm.cs

class Account
{
  // 出力したくない場合は [Ignore] を付ける
  // [Ignore]
  public int Id { get; set; }
  public string Name { get; set; }
  public DateTime CreatedAt { get; set; }
}

class Program
{
  static void Main(string[] args)
  {
    var config = new CsvConfiguration(CultureInfo.GetCultureInfo("ja-jp"))
    {
      // 全てダブルクォートで囲む
      Quote = '"',
      ShouldQuote = context => true,
      Encoding = Encoding.UTF8
    };

    var accounts = new Account[]
    {
      new Account
      {
        Id = 1,
        Name ="田中001",
        CreatedAt = DateTime.Parse("2018/01/01 01:00")
      },
      new Account
      {
        Id = 2,
        Name ="田中002",
        CreatedAt = DateTime.Parse("2018/01/02 02:00")
      },
      new Account
      {
        Id = 3,
        Name ="田中003",
        CreatedAt = DateTime.Parse("2018/01/03")
      }
    };

    using var csv = new CsvWriter(File.CreateText("accounts.csv"), config);
    // ヘッダ行を出力する
    csv.WriteHeader<Account>();
    csv.NextRecord();

    // データを出力する
    csv.WriteRecords(accounts);
  }
}

out.csv

"Id","Name","CreatedAt"
"1","田中001","2018/01/01 1:00:00"
"2","田中002","2018/01/02 2:00:00"
"3","田中003","2018/01/03 0:00:00"

FAQ

Q. UTF-8 BOMありで出力したいです。

A. 以下がサンプルプログラムです。

// var config = new CsvConfiguration();
using var streamWriter = new StreamWriter(File.Open("test.csv", FileMode.CreateNew), Encoding.UTF8);
using var csv = new CsvWriter(streamWriter, config);
// csv.WriteRecords(...);