C# generic Excel exporter using reflection -


i'm working on generic excel exporter in c#. point put collection of type , specify properties of class should exported using lambda expressions , have done that. problem i'm struggling when have complex property in class, property value exported "namespace.classname" (e.g. "myapp.viewmodels.myviewmodel").

here code:

excel exporter class:

    public class excelexporter     {         public void exporttoexcel<t>(ienumerable<t> data, params expression<func<t, object>>[] columns)         {             datatable datatable = this.converttodatatable(data, columns);                           //export datatable object excel using library...         }          private datatable converttodatatable<t>(ienumerable<t> data, params expression<func<t, object>>[] columnsfunc)         {             datatable table = new datatable();              foreach (var column in columnsfunc)             {                 string columnname = reflectionutility.getpropertydisplayname<t>(column);                 table.columns.add(columnname);             }              foreach (t obj in data)             {                 datarow row = table.newrow();                  (int = 0; < table.columns.count; i++)                 {                     row[table.columns[i].columnname] = reflectionutility.getpropertyvalue<t>(obj, columnsfunc[i]);                 }                  table.rows.add(row);             }              return table;          } 

reflectionutility class - provides methods property name , value. "getpropertydisplayname" method reads [displayname] attribute value property , sets header column in excel document (the reason i'd property 'firstname' displayed 'first name').

public static class reflectionutility     {         /// <summary>         /// returns display name of property (set using [displayname] attribute).         /// if [displayname] not provided, returns actual property name.         /// </summary>         /// <typeparam name="t"></typeparam>         /// <param name="expression"></param>         /// <returns></returns>         public static string getpropertydisplayname<t>(expression<func<t, object>> expression)         {             var memberexpression = expression.body memberexpression;              if (memberexpression == null)             {                 memberexpression = ((unaryexpression)expression.body).operand memberexpression;             }              var property = memberexpression.member propertyinfo;              if (property != null)             {                 var displaynameattribute = property.getcustomattribute(typeof(displaynameattribute), false) displaynameattribute;                  if (displaynameattribute != null)                 {                     return displaynameattribute.displayname;                 }             }              return memberexpression.member.name;         }          public static object getpropertyvalue<t>(t obj, expression<func<t, object>> expression)         {             var memberexpression = expression.body memberexpression;              if (memberexpression == null)             {                 memberexpression = ((unaryexpression)expression.body).operand memberexpression;             }              var property = memberexpression.member propertyinfo;              if (property != null)             {                 // note: if want export complex object, object's value "namespace.classname",                 // inappropriate displaying. must specify additionally property complex object should visualized...                  var value = property.getvalue(obj);                  return value;             }              return null;         } 

how consume excelexporter class:

excelexporter excelexporter = new excelexporter();      excelexporter.exporttoexcel<myviewmodel>(genericlisttoexport,         p => p.stringproperty1,         p => p.stringproperty2,         p => p.complexproperty.intproperty1); 

how can pass complexproperty.intproperty1 , value of , handle case when complexproperty null, won't nullreferenceexception.

here test scenario excel output: enter image description here

any appreciated!

epplus can load ienumerable worksheet. means can load results of enumerable.select call restrict columns want, eg:

var products=allproducts.where(prod=>prod.customerid=14)                         .select(new {prod.name,prod.category}); sheet.cells["a1"].loadfromcollection(products); 

you can use if want, or can check how it's done in excelrangebase.loadfromcollection.

looking @ code, epplus looks displayname , description attributes generate header text, before falling member's name


Comments

Popular posts from this blog

javascript - oscilloscope of speaker input stops rendering after a few seconds -

javascript - gulp-nodemon - nodejs restart after file change - Error: listen EADDRINUSE events.js:85 -

Fatal Python error: Py_Initialize: unable to load the file system codec. ImportError: No module named 'encodings' -