BogusとCsvHelperでダミーデータのCSVを生成してみました。
Bogus
Bogusは、ダミーデータを生成するライブラリです。
CsvHelper
CsvHelperは、CSVを読み書きするライブラリです。
https://joshclose.github.io/CsvHelper/
インストール
NuGetでBogusとCsvHelperをインストールします。
ソースコード
説明するより、ソースをみてもらった方が早いと思います。Dump
とUtil.Image
はLINQPadで使えるメソッドです。
// using Bogus; // using Bogus.DataSets; // using CsvHelper; void Main() { // データ生成ルール var faker = new Faker<User>("ja") // 日本語 .RuleFor(u => u.ID, f => f.IndexFaker + 1) .RuleFor(u => u.Gender, f => f.PickRandom<Name.Gender>()) .RuleFor(u => u.FirstName, f => f.Name.FirstName()) .RuleFor(u => u.LastName, f => f.Name.LastName()) .RuleFor(u => u.FullName, (f, u) => $"{u.LastName} {u.FirstName}") .RuleFor(u => u.Email, f => f.Person.Email) .RuleFor(u => u.Age, f => f.Random.Number(18, 60)) .RuleFor(u => u.AvatarUrl, f => f.Internet.Avatar()) .RuleFor(u => u.DateOfBirth, f => f.Person.DateOfBirth) .RuleFor(u => u.Phone, f => f.Person.Phone) .RuleFor(u => u.Created, f => f.Date.Past()) .RuleFor(u => u.AndroidPushID, f => f.System.AndroidId()); // 生成 var fakes = faker.Generate(3); // 可視化 fakes.Dump("CSVデータ"); fakes.ForEach(f => Util.Image(f.AvatarUrl).Dump("アバター画像")); // CSV出力 using (var writer = File.CreateText(@"d:\users.csv")) { var csv = new CsvWriter(writer); csv.Configuration.HasHeaderRecord = true; csv.WriteRecords(fakes); } } public class User { public int ID { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public string FullName { get; set; } public Name.Gender Gender { get; set; } public string Email { get; set; } public int Age { get; set; } public string AvatarUrl { get; set; } public DateTime DateOfBirth { get; set; } public string Phone { get; set; } public DateTime Created { get; set; } public string AndroidPushID { get; set; } }
出力データ
Dumpした結果です。それらしいデータが出力されています。
CSV
出力されたCSVです。
ID,FirstName,LastName,FullName,Gender,Email,Age,AvatarUrl,DateOfBirth,Phone,Created,AndroidPushID 1,美咲,松本,松本 美咲,Male,Richard_40@yahoo.com,53,https://s3.amazonaws.com/uifaces/faces/twitter/nwdsha/128.jpg,1953/12/25 10:38:26,025-178-5701,2018/03/27 14:01:50,APA914SBIu3jYZflU9cfav8FGs-bXmrh5CYVIbmQ22_X3w5qnVzS7GRJzbQS6HGn3Pen0lEIQoc7veBanAQ1OA9sMgnxnvKnoFThjLq1hS2LtKelCGvzTEAwFOCM-7mlGRLSmlTE9ONXyq-221XI0awM5oDx8F38xJ5E-o_hPTp4SE-fPAKZcFl 2,陸斗,清水,清水 陸斗,Male,Shawna_42@yahoo.com,45,https://s3.amazonaws.com/uifaces/faces/twitter/anasnakawa/128.jpg,1994/12/30 8:28:39,006-917-4843,2017/12/08 23:26:56,APA91FJzrK46317uNW4Hhguh5U9p8eWpTlrePtjIwGLbpp0WsiqORr2mTpQJwlqcQIfLCVGlEpbCwiUJTgZSQ7Atj5mrEBcbgyoJahkyD49sgsRCw7RhoAoI7OtxAgJ2b0nZVbyDXrgM-7cSgLWwLYPIaHBpQP-oo6hg5TIlBflYkEK0BChQmcj 3,大和,山口,山口 大和,Male,Cindy_@gmail.com,32,https://s3.amazonaws.com/uifaces/faces/twitter/d33pthought/128.jpg,1950/11/05 16:54:33,03-0595-6835,2017/12/03 14:13:06,APA91jRe3RVnlBSv4rnXk6pbqGphV1pJ8PcI5UCeD1PlKuAbWOKc-nZaFa9YVBk2scfxoaqbR9lik4uY6cn7jcKNS22XLGk1KMUyf2PMpyoR2ISBIeRIfcLgutHm8vtbRjzzbYJ4qCLMRVL9ctfxQDPx1E3NnuEV5b_L8jpMwNjEu-rBKx9HgXo
大量データを出力する場合
プログラムでCSVを出力する方法は、特に大量データが必要なときに威力を発揮しますが、OutOfMemoryExceptionが発生しないように気を付ける必要があります。
Faker<T>.Generate
は、List<T>
を返すので、大量データを出力する場合は、CSV出力を分割します。
// using Bogus; // using Bogus.DataSets; // using CsvHelper; void Main() { // データ生成ルール var faker = new Faker<User>("ja") // 日本語 .RuleFor(u => u.ID, f => f.IndexFaker + 1) .RuleFor(u => u.Gender, f => f.PickRandom<Name.Gender>()) .RuleFor(u => u.FirstName, f => f.Name.FirstName()) .RuleFor(u => u.LastName, f => f.Name.LastName()) .RuleFor(u => u.FullName, (f, u) => $"{u.LastName} {u.FirstName}") .RuleFor(u => u.Email, f => f.Person.Email) .RuleFor(u => u.Age, f => f.Random.Number(18, 60)) .RuleFor(u => u.AvatarUrl, f => f.Internet.Avatar()) .RuleFor(u => u.DateOfBirth, f => f.Person.DateOfBirth) .RuleFor(u => u.Phone, f => f.Person.Phone) .RuleFor(u => u.Created, f => f.Date.Past()) .RuleFor(u => u.AndroidPushID, f => f.System.AndroidId()); // 100万行ずつに分ける using (var writer = File.CreateText(@"d:\manyusers.csv")) { var csv = new CsvWriter(writer); foreach (var i in Enumerable.Range(1, 10)) { csv.WriteRecords(faker.Generate(1000000)); } } }
もしくは、IEnumerable<T>
を返すGenerateForever
を使ってもOKです。