Epplus - LoadFromCollection and column order

4.2k Views Asked by At

I'm using the method LoadFromCollection to fill an excel with a List. However, the excel columns need to have a certain order to provide a better context for the user, so I'm trying to find out how to accomplish this.

One option I've is to set the order of the parameters inside the class, but I'm avoiding this because someone else can change their order and that will affect my code.

The second option I've is to use Linq:

var orderedColumns = (from p in myList 
                     select new { p.Name, p.Age, ...}).ToList();

This way I can also define the column order, but I don't like the idea of having to create an anonymous when I already have the list ready to be used (I also lose the DisplayNameAttribute that I defined for the class).

Do you guys have any ideas? Perhaps I could use MemberInfo[]?

1

There are 1 best solutions below

2
On

I've found a solution that I'll share with you guys.

public class MyClass
{
   [DataMember(Order = 1)]
   public string PropertyA;

   [DataMember(Order = 2)]
   public int PropertyB

   [DataMember(Order = 0)]
   public bool propertyC
}

With the code like this, if I have a List<MyClass> and use the LoadFromCollection() from Epplus the resulting excel will show the columns in the order to which they appear in the class:

PropertyA | PropertyB | PropertyC

To solve this problem, we can do the following:

var orderedProperties = (from property in typeof(MyClass).GetProperties()
                         where Attribute.IsDefined(property, typeof(DataMemberAttribute))
                         orderby ((DataMemberAttribute)property
                                  .GetCustomAttributes(typeof(DataMemberAttribute), false)
                                  .Single()).Order
                         select property);

var ws = p.Workbook.Worksheets.Add("MySheet");
ws.Cells[1, 1].LoadFromCollection(myClassCollection, true, OfficeOpenXml.Table.TableStyles.Light1
   ,System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public
   ,orderedProperties.ToArray());

The resulting excel will show this columns order:

PropertyC | PropertyA | PropertyB

Note: only the columns with the [DataMember(Order = x)] attribute will show up on the excel, but I also wanted to achieve this because there are some columns of my class that I don't want to show in the excel.

Credits to @Sanjay for mentioning the DataMember attribute.