CsvHelperでいちいちMapをつくるのめんどくさい。
CsvHelperでジェネリックにCsvファイルを読み書きしたい!
そんなときはこれで解決
このコードで、クラスのプロパティの文字列に一致したHeaderを持つCsvファイルを読み込んだり書き込んだりしてくれます。
読み込み
ReadCsv.cs
public static List<T> Read<T>(string filepath)
{
using (var reader = new StreamReader(filepath))
using (var csv = new CsvReader(reader, CultureInfo.CurrentCulture))
return csv.GetRecords<T>().ToList();
}
書き込み
WriteCsv.cs
public static void Write<T>(IEnumerable<T> objs, string filepath)
{
using (var reader = new StreamWriter(filepath))
using (var csv = new CsvWriter(reader, CultureInfo.CurrentCulture))
csv.WriteRecords<T>(objs);
}
Appendix
CsvじゃなくてTsv(区切り文字の設定)とかEncoderの設定
より汎用的にちょっとコードを加えてみる
たまにカンマ,じゃなくてタブ区切りのデータ処理とかしたいときある。そんなときもCsvHelper。
たまにはUTF-8,じゃなくて"Shift-JIS"で処理とかしたいときもある。そんなときもCsvHelper。
読み込み
ReadCsv.cs
public static List<T> Read<T>(string filepath, Encoding encoding, string delimiter)
{
using (var reader = new StreamReader(filepath,encoding))
using (var csv = new CsvReader(reader, CultureInfo.CurrentCulture))
{
csv.Configuration.Delimiter = delimiter;
return csv.GetRecords<T>().ToList();
}
}
書き込み
WriteCsv.cs
public static void Write<T>(IEnumerable<T> obj, string filepath, Encoding encoding, string delimiter)
{
using (var reader = new StreamWriter(filepath, false, encoding))
using (var csv = new CsvWriter(reader, CultureInfo.CurrentCulture))
{
csv.Configuration.Delimiter = delimiter;
csv.WriteRecords<T>(obj);
}
}
使いやすくstatic classでまとめる
こんな感じでつかいましょう。
CsvParser.cs
public static class CsvParser
{
//簡易バージョン
public static List<T> Read<T>(string filepath)
{
using (var reader = new StreamReader(filepath))
using (var csv = new CsvReader(reader, CultureInfo.CurrentCulture))
return csv.GetRecords<T>().ToList();
}
public static void Write<T>(IEnumerable<T> obj, string filepath)
{
using (var reader = new StreamWriter(filepath))
using (var csv = new CsvWriter(reader, CultureInfo.CurrentCulture))
csv.WriteRecords<T>(obj);
}
//encoderと区切り文字設定できるバージョン
public static List<T> Read<T>(string filepath, Encoding encoding, string delimiter)
{
using (var reader = new StreamReader(filepath,encoding))
using (var csv = new CsvReader(reader, CultureInfo.CurrentCulture))
{
csv.Configuration.Delimiter = delimiter;
return csv.GetRecords<T>().ToList();
}
}
public static void Write<T>(IEnumerable<T> obj, string filepath, Encoding encoding, string delimiter)
{
using (var reader = new StreamWriter(filepath, false, encoding))
using (var csv = new CsvWriter(reader, CultureInfo.CurrentCulture))
{
csv.Configuration.Delimiter = delimiter;
csv.WriteRecords<T>(obj);
}
}
}
使い方
Test.cs
//Shift-JISでカンマ区切りのデータを読み込む
var data=CsvParser.Read<MyClass>(@"filepath.csv",Encoding.GetEncoding("Shift_JIS"), ",");
//読み込んだデータをタブ区切りで新しいファイルに書き込む
CsvParser.Write<MyClass>(data,@"filepath.tsv",Encoding.GetEncoding("Shift_JIS"), "\t");
対応するヘッダーがない
ちなみにクラスに対応するHeaderがないときはエラーになってしまう。。。
そんなときは!
MyClass.cs
public class MyClass
{
[Index(0)]
public DateTime Date { get; set; }
[Index(1)]
public double Value { get; set; }
}
みたいな感じでAttributionをつければいい感じに読み取ってくれます。
まとめ
多分これが一番シンプルで汎用性が高い!と思ってる。
いままでのコードが激減するかも。