2010-06-08 7 views
3

FileHelpers을 사용하여 나는 [DelimitedRecord(",")]으로 클래스를 꾸며서 해당 유형의 객체 열거를 CSV로 출력하려고합니다. 하지만, 내 수업이 ActiveRecordLinqBase<T>에서 상속 받기 때문에 문제가 발생했습니다..NET 익명 형식의 열거 형에서 csv를 출력하는 방법은 무엇입니까?

그래서 익명 형식의 열거 형을 선택할 수 있고 어떻게 든 filehelpers에서 CSV를 생성 할 수 있는지 궁금합니다. 나는 csv를 출력하기 위해 단지 FileHelpers를위한 클래스를 정의 할 필요가 없다.

다른 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로 출력하는 것은 상당히 사소한 작업이지만 제 3 자 라이브러리를 사용하기 때문에 더 복잡한 작업을 수행한다고 가정합니다. 개체 컬렉션이 있고 이러한 개체가 포함 된 CSV 출력 파일을 생성하려고합니다 (개체를 .ToString로 지정하거나 형식 이름 등을 출력하려고한다고 가정)? –

답변

3

LINQ To CSV은 저에게 큰 도움이되었습니다. 여기

내가 그것을 사용하고 방법의 예 :

  • 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 레코드 용 클래스를 만들겠다고 결심했습니다. 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); 
    } 
} 
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

데이터에서 분리 문자로 이스케이프 처리를 추가해야합니다. –

+1

+1 Matt : 이것이 바로 CSV 생성을위한 자체 논리를 작성하지 않을 이유입니다. 당신은 하나의 가장자리 사건을 언급했다. 너무 많다. 왜 검증 된 라이브러리를 사용하지 않습니까? –

관련 문제