CSVWriter-自作Entityオブジェクトをcsv出力

CSVの出力が列のレイアウトが変わるたびに作るのが面倒だったので作りました。

これで簡単なEntityのListオブジェクトをCSVに出力することができます。

プログラム

Imports System.IO.StreamWriter
Imports System.Reflection

Public Class CSVWriter(Of T)

    Public Sub SaveEntities(entities As List(Of T), filePath As String, Optional ByVal appendMode As Boolean = False)
        Dim writer As IO.StreamWriter
        Dim propertyNames As List(Of String)
        Dim recodeData As New List(Of String)

        writer = New IO.StreamWriter(filePath, appendMode, System.Text.Encoding.GetEncoding("shift_jis"))

        'プロパティ名の取得&書き込み
        propertyNames = GetPropertyNames(entities.First)

        'CSVファイルの1行目に列名を書き込む
        writer.WriteLine(String.Join(",", propertyNames.ToArray()))

        '値の書き込み
        For Each entity In entities
            recodeData.Clear()

            For Each prop In propertyNames
                'スペースやカンマなどを取り込める用に変更する予定
                recodeData.Add(GetData(entity, prop))
            Next

            writer.WriteLine(String.Join(",", recodeData.ToArray()))
        Next

        writer.Dispose()
    End Sub

    Private Function GetPropertyNames(entity As T) As List(Of String)
        Dim names As New List(Of String)

        For Each member In entity.GetType.GetProperties()
            names.Add(member.Name)
        Next

        Return names
    End Function

    Private Function GetData(entity As T, propertyName As String) As String
        Dim result As String
        Dim members As PropertyInfo()
        Dim member As PropertyInfo

        members = entity.GetType.GetProperties
        member = members.Where(Function(x) x.Name = propertyName).FirstOrDefault
        result = member.GetValue(entity)

        Return result
    End Function

End Class

使い方

まずは適当に作ったEntityクラスです。

Public Class Ingredient
    Property id As Integer
    Property Name As String
    Property Quantity As String

    Public Sub New(ByVal id As Integer, ByVal name As String, ByVal quantity As String)
        Me.id = id
        Me.Name = name
        Me.Quantity = quantity
    End Sub
End Class

次に、実際にCSVWriterクラスを実行した例です

Dim recipe As New List(Of Ingredient)

recipe.Add(New Ingredient(1, "米", "1合"))
recipe.Add(New Ingredient(2, "オリーブオイル", "大さじ2"))
recipe.Add(New Ingredient(3, "ブイヨン", "3カップ"))
recipe.Add(New Ingredient(4, "白ワイン", "大さじ1"))
recipe.Add(New Ingredient(5, "バター", "20g"))
recipe.Add(New Ingredient(6, "パルミジャーノ・チーズ", "50g"))
recipe.Add(New Ingredient(7, "塩", "少々"))
recipe.Add(New Ingredient(8, "粗びき黒こしょう", "少々"))

Dim writer As New CSVWriter(Of Ingredient)
writer.SaveEntities(recipe, "C:\Temp\output.csv")

実行するとModule1.vbの13行目で指定したフォルダに「output.csv」というファイル名でcsvファイルが保存されます。

実際にメモ帳などで開くと次のような結果が書き込まれます。

id,Name,Quantity
1,米,1合
2,オリーブオイル,大さじ2
3,ブイヨン,3カップ
4,白ワイン,大さじ1
5,バター,20g
6,パルミジャーノ・チーズ,50g
7,塩,少々
8,粗びき黒こしょう,少々

解説

このクラスのポイントは2つです。

  • Genericの利用
  • PropetyInfoの利用

これにより、汎用性の高いcsv出力クラスになりました。あとはIngredientのようなEntityクラスを作るだけで様々なcsvファイルを出力することができます。

ただ、コメントでも書いている通りスペースやカンマが入ってしまうとプログラムに読み込むときに失敗します。時間があるときに改良予定。

ステップ毎に何をやっていか知りたいというご要望が、もし仮にある場合は、お問合せで構いませんのでご連絡ください。すぐに作成してアップします。笑

もちろんReaderも作ってます

CSVReaderはこちらを参考にしてください。

コメント

タイトルとURLをコピーしました