2010-06-08 62 views
3

使用FileHelpers,我用[DelimitedRecord(",")]裝飾了一個類,並將輸出該類型的對象的枚舉爲CSV。但是,它不起作用,因爲我的課程從ActiveRecordLinqBase<T>繼承,這導致了一些問題。.NET如何從匿名類型的枚舉中輸出csv?

所以,我想知道如果我可以只選擇匿名類型的枚舉,並以某種方式讓文件幫助從中生成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..... 
+0

我不知道我完全理解你的問題。可以發佈一段代碼,顯示你正在嘗試做什麼?輸出到CSV是一項相當簡單的任務,但我認爲您正在嘗試做更復雜的事情,因此需要使用第三方庫。 據我所知,你有一個對象的集合,你想生成一個包含這些對象的CSV輸出文件(我假設你想要.ToString對象或輸出類型名稱或其他)? – 2010-06-08 21:49:45

回答

3

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(); 
} 

UPDATE

也有一些缺點上面的方法:

  • 在CSV文件中的列順序是不可預測的。它不遵循匿名類型中的屬性定義的順序。
  • 列標題來自屬性名稱,它並不總是符合要求。

所以,我決定爲CSV記錄創建一個類,它不會比匿名類型做更多的工作。我使用Auto Mapper來壓扁我的源類並填充CSV類的屬性值。我也決定比較FileHelpersLinq To CSVLinq To CSV是明顯的贏家,在我的情況:

  • L2CSV允許你申請一個屬性每個屬性的類定義的列順序,列標題標題和轉換格式。
  • FHs只會讓您爲每個字段提供轉換格式。列順序取決於在類中定義的屬性的順序。
  • FHS不會推斷屬性名稱的列標題,也沒有讓你提供一個。你可以提供一個文本字符串作爲標題爲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); 
    } 
} 
2

你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; 
} 
+2

您需要爲數據中的分隔字符添加某種轉義。 – 2010-06-09 13:20:11

+1

+1 Matt:這正是我爲什麼不寫自己的邏輯來生成csv的原因。你提到了一個邊緣案例。太多了。爲什麼不使用經過驗證的庫? – 2010-06-09 13:27:45