4

FileHelpersを使用してクラスを装飾し、[DelimitedRecord(",")]そのタイプのオブジェクトの列挙を CSV として出力しようとしていました。しかし、私のクラスは から継承しているため、うまくいきませんでしたActiveRecordLinqBase<T>。これにより、いくつかの問題が発生しました。

そのため、匿名型の列挙を選択して、それからファイルヘルパーに csv を生成させることができるかどうか疑問に思っていました。FileHelpers が csv を出力するためだけにクラスを定義する必要はありません。

私は別のcsvライブラリを使用することにオープンですが、FileHelpersは証明されています.

編集

@Foovanadil:これは私がやろうとしているようなものです:

CreateCSV(MyCollection.Select(x=>new{
    x.Prop1,
    x.Prop2,
    x.Prop3
}));

あなたにあげる:

Prop1,Prop2,Prop3
val1a,val2a,val3a
val1b,val2b,val3b
etc.....
4

2 に答える 2

4

LINQ To CSVは私にとってはうまくいきました。

これが私がそれをどのように使用しているかの例です:

protected void Page_Load(object sender, EventArgs e)
{
    var courseId = int.Parse(Request["id"]);
    var course = Course.Queryable.Single(x => x.Id == courseId);
    Response.ContentType = "text/csv";
    Response.AddHeader("Content-Disposition", string.Format("attachment;filename=\"{0}.csv\";", course.Code));

    var csvContext = new LINQtoCSV.CsvContext();
    var writer = new System.IO.StreamWriter(Response.OutputStream);
    csvContext.Write(course.Registrations.Select(x => new
    {
        x.StudentId,
        x.Name,
        x.EmailAddress,
        x.MoodleUsername,
        x.Age,
        x.Is65OrOlder,
        x.CertificationAndRank,
        x.Citizenship,
        x.DateOfBirth,
        x.DepartmentName,
        x.StationNumber,        
        x.EmploymentStatus,
        x.HighestEducationLevel
    }), writer);        

    writer.Dispose();
}

アップデート

上記のアプローチにはいくつかの欠点があります。

  • csv ファイルの列の順序は予測できません。匿名型のプロパティ定義の順序には従いません。
  • 列ヘッダーは、常に望ましいとは限らないプロパティ名から取得されます。

そこで、CSV レコード専用のクラスを作成することにしました。これは、匿名型よりも多くの作業を行うことにはなりませんでした。Auto Mapperを使用してソース クラスをフラット化し、CSV クラスのプロパティ値を設定しました。また、 FileHelpersLinq To CSVと比較することにしました。私の状況では、 Linq To CSVが明らかに勝者でした。

  • L2CSV では、クラス内の各プロパティに属性を適用して、列の順序、列ヘッダーのタイトル、および変換形式を定義できました。
  • FH では、各フィールドの変換形式のみを指定できます。列の順序は、クラスで定義されているプロパティの順序に依存していました。
  • FH は、プロパティ名から列ヘッダーを推測したり、列ヘッダーを指定したりしません。CSV ファイルのヘッダーとしてリテラル文字列を指定できますが、これは適切ではありません。区切り文字はリテラル文字列に組み込まれています。列のタイトルの順序は、プロパティの順序と同期されていません。

これらの発見が役に立つことを願っています。ここに私の新しいコードがあります:

// CSV Class

public class CsvRegistration
{
    [CsvColumn(FieldIndex = 0)]
    public string Name { get; set; }

    [CsvColumn(FieldIndex = 1, Name = "Student Id")]
    public int StudentId { get; set; }

    [CsvColumn(FieldIndex = 2, Name = "Email Address")]
    public string EmailAddress { get; set; }

    [CsvColumn(FieldIndex = 3, Name = "Moodle Username")]
    public string MoodleUsername { get; set; }

    [CsvColumn(FieldIndex = 4, Name = "Dept. Name")]
    public string DepartmentName { get; set; }

    [CsvColumn(FieldIndex = 5, Name = "Station #")]
    public string StationNumber { get; set; }

    [CsvColumn(FieldIndex = 6, Name = "Highest Education Level")]
    public string HighestEducationLevel { get; set; }

    [CsvColumn(FieldIndex = 7, Name = "Certification/Rank")]
    public string CertificationAndRank { get; set; }

    [CsvColumn(FieldIndex = 8, Name = "Employment Status")]
    public string EmploymentStatus { get; set; }

    [CsvColumn(FieldIndex = 9, Name = "Registration Date")]
    public DateTime RegistrationDate { get; set; }

    [CsvColumn(FieldIndex = 10, Name = "Date of Birth")]
    public DateTime DateOfBirth { get; set; }

    [CsvColumn(FieldIndex = 11)]
    public int Age { get; set; }

    [CsvColumn(FieldIndex = 12)]
    public string Citizenship { get; set; }

    [CsvColumn(FieldIndex = 13)]
    public string Race { get; set; }

    [CsvColumn(FieldIndex = 14)]
    public string Ethnicity { get; set; }

    [CsvColumn(FieldIndex = 15, Name = "Home Address")]
    public string HomeAddressLine1 { get; set; }

    [CsvColumn(FieldIndex = 16, Name = "City")]
    public string HomeAddressCity { get; set; }

    [CsvColumn(FieldIndex = 17, Name = "State")]
    public string HomeAddressState { get; set; }

    [CsvColumn(FieldIndex = 18, Name = "Zip")]
    public string HomeAddressZip { get; set; }

    [CsvColumn(FieldIndex = 19, Name = "County")]
    public string HomeAddressCounty { get; set; }

    [CsvColumn(FieldIndex = 20, Name = "Home Phone")]
    public string HomePhone { get; set; }

    [CsvColumn(FieldIndex = 21, Name = "Work Phone")]
    public string WorkPhone { get; set; }
}


// ASPX page to serve csv file

protected void Page_Load(object sender, EventArgs e)
{
    var courseId = int.Parse(Request["id"]);
    var course = Course.Queryable.Single(x => x.Id == courseId);
    Response.ContentType = "text/csv";
    Response.AddHeader("Content-Disposition", string.Format("attachment;filename=\"{0}.csv\";", course.Code));

    using (var writer = new System.IO.StreamWriter(Response.OutputStream))
    {
        var registrations = Mapper.Map<IEnumerable<Registration>, IEnumerable<CsvRegistration>>(course.Registrations);
        var cc = new LINQtoCSV.CsvContext();
        cc.Write(registrations, writer);
    }
}
于 2010-06-09T13:30:11.113 に答える
3

CreateCSV リストは次のようになります。

static StringBuilder CreateCSV<T>( IEnumerable<T> data )
{
    StringBuilder builder = new StringBuilder();
    var properties = typeof( T ).GetProperties();

    foreach ( var prop in properties )
    {   
        builder.Append( prop.Name ).Append( ", " );
    }

    builder.Remove( builder.Length - 2, 2 ).AppendLine();

    foreach ( var row in data )
    {
        foreach ( var prop in properties )
        {
            builder.Append( prop.GetValue( row, null ) ).Append( ", " );
        }

        builder.Remove( builder.Length - 2, 2 ).AppendLine();
    }

    return builder;
}
于 2010-06-09T13:17:31.293 に答える