2012-02-15 2 views
3

속성에 표시 이름이있는 viewmodel이 있습니다. 현재 웹 페이지의 그리드와 동일한 데이터가 포함 된 엑셀 시트를 만들고 있습니다. closed xml (openxml을 사용하는)을 사용하여 엑셀 시트를 서버에 생성하고 엑셀로 데이터를 다운로드하고자 할 때 웹 클라이언트에게 보냅니다. Excel의 openxml 스트림에 헤더 행을 쓸 때 이미 정의한 displayname을 다시 사용하고 싶습니다. 그러나 나는 무엇을 부를지 알아낼 수 없다. 다음은 표시 이름의 예입니다. (I 만이 사용하는 예를 들어, 현실은 많은 더 많은 열이 있습니다) :System.ComponentModel.DataAnnotations 필드의 표시 이름 속성에 액세스하는 방법

using System.ComponentModel.DataAnnotations; 
public class DCArrival : IDCArrival 
{ 
    [Display(Name = "Via Transit")] 
    public String LocationType { get; set; } 
    [Display(Name = "Currency")] 
    String CurrencyISOCode { get; } 
} 

그럼 내가 헤더 행을 만들 때이 표시 이름을 사용하고 싶습니다. 마크 내가 잡고 싶어하는지 설명 할 tryes 의사 코드 :

private MemoryStream CreateExcelFile(ICollection<DCArrival> dcArrToShow 
, QueryStrInput queryStrInput) 
    { 
     try 
     { 
      // Create an Excel Workbook 
      XLWorkbook wb = new XLWorkbook(); 
      // Add the worksheet with data 
      IXLWorksheet ws = wb.Worksheets.Add("New Worksheet"); 
      // Add my data that was displayed in the html table ... 
      ws.Cell(1, 1).SetValue("Hello World"); 
      //Add Header row. By taking a object in the collection and figure out its 
      // display name 
      DCArrival firstRow = dcArrToShow.First(); 
      // Here comes my problem. Here is my dream up mockup code 

      ws.Cell(2,1).Value = firstRow.LocationType.DisplayAttribute.GetName() 
      ws.Cell(2,2).Value = firstRow.CurrencyISOCode.DisplayAttribute.GetName() 
      // back to reality 
      //this is how easy I can get all data from Collection 
      ws.Cell(3, 1).Value = dcArrToShow.AsEnumerable(); 
      // All done 
      MemoryStream ms = new MemoryStream(); 
      wb.SaveAs(ms); 
      return ms; 
     } 
     catch (Exception e) 
     { 
      string errmsg = String.Format("Failed to create Excel file: {0}", 
      e.Message); 
      throw new Exception(errmsg, e); 
     } 

나는 http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.displayattribute.aspx 살펴 보았습니다을하지만 그것을 잡아 어떻게 이해하지 않습니다. 정상적인 mvc 3 html 렌더링을 사용할 때 이것이 마술처럼 고정되어 있음을 이해합니다.

ws.Cell(2.1).Value = ModelMetadata.FromLambdaExpression<DCArrival, string>(x => x.LocationType, new ViewDataDictionary<DCArrival>(firstRow)).DisplayName; 

또는 확장 메서드 쓰기 : 내가 MVC 3에서 기본적인 검증을 설명하고 싶어 내가 블로그에서 익사 얻을 이러한 개념을 구글로하면

+0

내가 표시 이름 데이터 주석 값 FR에 액세스 할 수있는 방법 [이 링크를 참조 OM 코드] [1] [1] : http://stackoverflow.com/questions/3485737/how-can-i-access-the-displayname-data-annotation-value-from-code – MikMark

답변

3

당신은 모델 메타 데이터를 검색 할 수

public static class ModelMetadataExtensions 
{ 
    public static string GetName<TModel, TProperty>(this TModel model, Expression<Func<TModel, TProperty>> ex) 
    { 
     return ModelMetadata 
      .FromLambdaExpression<TModel, TProperty>(ex, new ViewDataDictionary<TModel>(model)) 
      .DisplayName; 
    } 
} 
을 다음

과 :

ws.Cell(2.1).Value = firstRow.GetName(x => x.LocationType); 
ws.Cell(2.2).Value = firstRow.GetName(x => x.CurrencyISOCode); 

UPDATE :

var properties = typeof(DCArrival).GetProperties(); 
foreach (var property in properties) 
{ 
    var displayAttribute = property 
     .GetCustomAttributes(typeof(DisplayAttribute), true) 
     .FirstOrDefault() as DisplayAttribute; 
    string displayName = property.Name; 
    if (displayAttribute != null) 
    { 
     displayName = displayAttribute.Name; 
    } 

    // TODO: do something with the display name for this property 
} 
+0

나는 (첫 번째 값)을 이해하지 못한다 : ws.Cell (2,1) .Value = ModelMetadata.FromLambdaExpression (x => x.LocationType, new ViewDataDictionary ()). DisplayName; 잘 처리되었습니다. 고맙습니다. –

+0

@ PatrikLindström, 오타였습니다. 'firstRow' 여야합니다. 나는 그것을 고쳤다. –

+0

정교하고 DCArrival의 모든 멤버를 반복하고 싶다면 어떻게해야할까요? tryed하지만 DisplayName은 항상 null입니다. 유형 type = typeof (DCArrival); PropertyInfo [] 속성 = type.GetProperties(); foreach (속성의 PropertyInfo 속성) { 문자열 displayName = ModelMetadata.FromLambdaExpression (x => 속성입니다.이름, 새 ViewDataDictionary (firstRow)). DisplayName; ws.Cell (startRow, j ++). 값 = displayName; } –

1

너희들이 그것을하고있는 모든 속성을 통해 루프를 위해 코멘트 섹션으로 표현하고 다음 사용할 수있는 속성 표시를 읽은 새로운 요구 사항에 따라

잘못 ...

static void Main() 
{ 

    var wb = new XLWorkbook(); 
    var ws = wb.Worksheets.Add("People"); 

    var people = new List<Person> 
    { 
     new Person{Name = "John Doe", DOB = new DateTime(1980,1,1)}, 
     new Person{Name = "Jane Doe", DOB = new DateTime(1985,1,1)} 
    }; 

    ws.FirstCell().InsertTable(people); 

    ws.Columns().AdjustToContents(); 
    wb.SaveAs(@"C:\MyFiles\Excel Files\Sandbox.xlsx"); 
} 

class Person 
{ 
    [Display(Name = "Person's Name")] 
    public String Name { get; set; } 

    [Display(Name = "Date of Birth")] 
    public DateTime DOB { get; set; } 
} 

enter image description here

+0

예 내가 closedxml http://closedxml.codeplex.com/wikipage?title=Inserting%20Tables&referringTitle=Documentation의 문서 비트를보고 싶습니다. 이제 CustomAttributes에 대한 완전한 제어권을가집니다. 감사 –

관련 문제