CsvWriter,CsvReaderとは
正式にはCsvHelperというライブラリに含まれる読み書きするためのクラスで、CSVファイルを簡単に扱うためのOSSライブラリです。
実行環境
記事執筆時は以下の実行環境で確認しています。
.NET 6
Windows11
ConsoleApplication
CsvHelper Version 30.0.1
インストール
使い方
Attributes
CsvHelperでは値を独自のクラスにマッピングして読み書きします。
作成したクラスに属性を指定する事でカラム名やカラム位置を指定したり、bool型を指定の文字列として出力する事が可能です。
以下に使用頻度の高い属性を記載します。
属性名 | 設定値 | 説明 |
---|---|---|
Name | 文字列 | カラム名を指定します。 |
Index | 数値 | カラムの位置を指定します。(1始まり) Index,Nameどちらも指定しない場合、読込み時はCSVのカラム順とプロパティ順、型を合わせないとエラーになるっぽいです。 |
BooleanTrueValues | 文字列 | bool型のプロパティがtrueの場合に出力する値を指定します。 |
BooleanFalseValues | 文字列 | bool型のプロパティがfalseの場合に出力する値を指定します。 |
Constant | 文字列 | 固定値を指定します。 プロパティの設定値に関係なく固定値が使用されます。 |
Optional | 必須ではないカラムに指定します。 出力時:Optional属性を指定したカラムは値がnullの場合は出力されません。 入力時:Optional属性を指定したカラムが存在しない場合対象のカラムは読み込まれません。 | |
Ignore | 読み書きの対象外とするプロパティを指定します。 |
読み書きに使用するクラス
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
public record CsvRecord { [Name("ID")] [Index(1)] public int Id { get; set; } = default!; [Name("名前")] [Index(2)] public string Name { get; set; } = default!; [Name("誕生日")] [Index(3)] public DateTime BirthDate { get; set; } = default!; [BooleanTrueValues("日本人")] [BooleanFalseValues("外国人")] [Index(4)] public bool IsJapanese { get; set; } = default!; [Constant("固定値")] [Index(5)] public string? Constant { get; set; } [Optional] [Name("備考")] [Index(6)] public string? Optional { get; set; } [Ignore] public string? Ignored { get; set; } } |
CsvConfiguration(設定)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
// shift-jisを.NET 6で使用出来るように登録する Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); var encoding = Encoding.GetEncoding("shift-jis"); var config = new CsvConfiguration(CultureInfo.CurrentCulture) { AllowComments = true, // コメントを許可するか(default:false) Comment = '#', // コメントとして扱う行を示す文字(default:#) HasHeaderRecord = true, // ヘッダー行の有無(default:true) Delimiter = ",", // 区切り文字(default:#) Encoding = encoding, // 文字コード指定(default:UTF-8) IgnoreBlankLines = true, // 空行を無視するかどうか(default:true) TrimOptions = TrimOptions.Trim, // 値のトリムオプション Quote = '"', // 値を囲む文字(default:'"') ShouldQuote = (args) => true, // 出力時に値をQuoteで指定した文字で囲むかどうか }; |
CsvWriter(出力)
「読み書きに使用するクラス」で作成したクラスを出力する例と結果を記載します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
using CsvHelper; using CsvHelper.Configuration; using CsvHelper.Configuration.Attributes; using System.Globalization; using System.Text; var records = new List<CsvRecord>() { new (){ Id = 1, Name = "田中太郎", BirthDate = new DateTime(1991, 3, 4), IsJapanese = true, Constant = "固定値が設定される", Ignored = "出力されない項目" }, new (){ Id = 2, Name = "プーチン", BirthDate = new DateTime(1952, 10, 7), IsJapanese = false, Ignored = "出力されない項目" }, new (){ Id = 3, Name = "山田花子", BirthDate = new DateTime(2012, 5, 12), IsJapanese = true, Constant = "固定値が設定される", Ignored = "出力されない項目" }, new (){ Id = 4, Name = "チェホンマン", BirthDate = new DateTime(1980, 10, 30), IsJapanese = false, Ignored = "出力されない項目" }, new (){ Id = 5, Name = "ゴリヘイ", BirthDate = new DateTime(1961, 11, 9), IsJapanese = true, Ignored = "出力されない項目" }, }; // shift-jisを.NET 6で使用出来るように登録する Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); var encoding = Encoding.GetEncoding("shift-jis"); var config = new CsvConfiguration(CultureInfo.CurrentCulture) { AllowComments = true, // コメントを許可するか(default:false) Comment = '#', // コメントとして扱う行を示す文字(default:#) HasHeaderRecord = true, // ヘッダー行の有無(default:true) Delimiter = ",", // 区切り文字(default:#) Encoding = encoding, // 文字コード指定(default:UTF-8) IgnoreBlankLines = true, // 空行を無視するかどうか(default:true) TrimOptions = TrimOptions.Trim, // 値のトリムオプション Quote = '"', // 値を囲む文字(default:'"') ShouldQuote = (args) => true, // 出力時に値をQuoteで指定した文字で囲むかどうか }; using var stream = new StreamWriter("test.csv", false, encoding); using var csv = new CsvWriter(stream, config); // CSV出力 csv.WriteRecords(records); |
出力結果
CsvReader(入力)
CsvWriterで出力したCSVを取り込む例と結果を記載します。
(IsJapanese列はbool型のため、CSVの内容を日本人→true,外国人→falseに変更しています。)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
using var stream = new StreamReader("test.csv", encoding); using var csv = new CsvReader(stream, config); // ヘッダー行取得 //NOTE:ヘッダーを内容より先に取得する場合は面倒だけど、Read(),ReadHeader()を使用してからでなければHeaderRecordに値は設定されない。 //NOTE:GetRecords()の後であればRead(),ReadHeader()は不要 csv.Read(); csv.ReadHeader(); Console.WriteLine(string.Join(",", csv.HeaderRecord!)); // 内容取得 foreach (var record in csv.GetRecords<CsvRecord>()) { Console.WriteLine(record); } |
入力結果
1 2 3 4 5 6 |
ID,名前,誕生日,IsJapanese,Constant,備考 CsvRecord { Id = 1, Name = 田中太郎, BirthDate = 1991/03/04 0:00:00, IsJapanese = True, Constant = 固定値, Optional = , Ignored = } CsvRecord { Id = 2, Name = プーチン, BirthDate = 1952/10/07 0:00:00, IsJapanese = False, Constant = 固定値, Optional = , Ignored = } CsvRecord { Id = 3, Name = 山田花子, BirthDate = 2012/05/12 0:00:00, IsJapanese = True, Constant = 固定値, Optional = , Ignored = } CsvRecord { Id = 4, Name = チェホンマン, BirthDate = 1980/10/30 0:00:00, IsJapanese = False, Constant = 固定値, Optional = , Ignored = } CsvRecord { Id = 5, Name = ゴリヘイ, BirthDate = 1961/11/09 0:00:00, IsJapanese = True, Constant = 固定値, Optional = , Ignored = } |
コメント