Click here to Skip to main content
12,689,968 members (27,619 online)
Click here to Skip to main content
Add your own
alternative version

Stats

9.7K views
6 bookmarked
Posted

Embrace Reflection and Export Any List Collection to CSV

, 29 Oct 2012 CPOL
Rate this:
Please Sign up or sign in to vote.
Embrace reflection and export any List collection to CSV

Introduction

It has become a very common request in recent data driven apps to be able to export certain data as CSV format. CSV format became widely used and acceptable. And it's very common that an individual app contains several such export features that take different object collection with respect to different needs and export to CSV, so here is where the problem lies. The goal of this post is to provide a generic solution using .NET Reflection and Generics so same export can be reusable though the entire application disrespect to object type and save our (programmers: most hardworking creatures on this planet after ant 8-) ) effort.

Problem Statement

I have seen programmers invest several hours to build such export features that satisfy different needs. So what happens for different object collection - programmers write different export methods that address particular export feature. Why is that? The answer is simple - each object has a different property so CSV contains different column name for each object. So programmers write different export functions that address a specific object type and arrange the CSV column name statically.

How Reflection Can Help

To address this issue, we can use .NET Generics and Reflection. I will not discuss about these wonderful features, instead of that, I will utilize those features to find a solution. If you navigate to MSDN to see what reflection can do, you will see PropertyInfo (Hmm, this is all we need) .

Use PropertyInfo to discover information such as the name, data type, declaring type, reflected type, and read-only or writable status of a property, and to get or set property values.

So the idea is that we will use a Generic collection to export and use Reflection to iterate all property via PropertyInfo, thus we can get all property name/type, all that whatever the object collection is provided. Once we have property name/ type, we can do whatever data formatting or processing we need according to our needs. Say for a particular app, specification is whatever date time is exported to CSV, it should be formatted like ddMMYYY. As we have property type now, it's a piece of cake right? :)

Solution

Here is the method that takes Generic List<t> as parameter and uses reflection to iterate the type and export accordingly.

 /// <summary>
 /// Take object List as input and export to csv which will be prompt save as dialog
 /// </summary>
 /// <typeparam name="T">Type of object</typeparam>
 /// <param name="listToExport">Object list to export</param>
 /// <param name="seperateChar">character to use as scv separator</param>
 public static void ExportListToCSV<T>(List<T> listToExport, string seperateChar)
 {
 Int32 success = 0;
 StringBuilder export = new StringBuilder();
 try
 { 
 string seperator = "";
 StringBuilder builder = new StringBuilder();
 PropertyInfo[] fieldInfo = listToExport[0].GetType().GetProperties();
 foreach (PropertyInfo col in fieldInfo)
 {
   if (col.PropertyType != typeof(EntityKey) && col.PropertyType != typeof(EntityState))
 {
 builder.Append(seperator).Append(col.Name);
 seperator = seperateChar;
 }
 }
 export.AppendLine(builder.ToString());
 foreach (T dataItem in listToExport)
 {
 PropertyInfo[] allProperties = dataItem.GetType().GetProperties();
 seperator = "";
 StringBuilder builderTmp = new StringBuilder();
 foreach (PropertyInfo thisProperty in allProperties)
 {
  if (thisProperty.PropertyType != typeof(EntityKey) && 
      thisProperty.PropertyType != typeof(EntityKey))
 {
 object value = thisProperty.GetValue(dataItem, null);
 String propetyValue = (value == null ? String.Empty : value.ToString());
 builderTmp.Append(seperator).Append(propetyValue);
 seperator = seperateChar;
 }
 }
 ++success;
 export.AppendLine(builderTmp.ToString()); 
 }
 }
 catch (Exception ex)
 {
 throw ex;
 }
// finally { if (sr != null) { sr.Close(); } }
HttpContext.Current.Response.Clear();
 HttpContext.Current.Response.Buffer = true;
 HttpContext.Current.Response.ContentType = "application/CSV";
 HttpContext.Current.Response.AppendHeader
 ("content-disposition", "attachment;filename=FileName.csv");
 HttpContext.Current.Response.Charset = "";
 HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.NoCache);
 HttpContext.Current.Response.Write(export.ToString());
 HttpContext.Current.Response.End();
}

One thing you might notice above is:

if (thisProperty.PropertyType != typeof(EntityKey) &&
thisProperty.PropertyType != typeof(EntityKey))

Why do we need this checking? You see if you are using Entity Framework in your app, all entities have these two additional property types predefined and we don’t want them to be exported to CSV and confuse end user, do we? So additional checking is required to remove them. If you do not use Entity Framework, you don’t need to worry about this checking.

So you can see a simple trick can save lots of development effort, enjoy the free time. :)

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Shahriar Iqbal Chowdhury/Galib
Chief Technology Officer
Bangladesh Bangladesh
I am a Software Engineer and Microsoft .NET technology enthusiast. Professionally I worked on several business domains and on diverse platforms. I love to learn and share new .net technology and my experience I gather in my engineering career. You can find me from here

Personal Site
Personal Blog
FB MS enthusiasts group
About Me

You may also be interested in...

Comments and Discussions

 
QuestionThis is fantastic. Pin
Mehradzie26-Nov-14 20:35
professionalMehradzie26-Nov-14 20:35 
GeneralMy vote of 5 Pin
Monjurul Habib29-Oct-12 8:00
memberMonjurul Habib29-Oct-12 8:00 
GeneralRe: My vote of 5 Pin
Shahriar Iqbal Chowdhury29-Oct-12 22:36
memberShahriar Iqbal Chowdhury29-Oct-12 22:36 
SuggestionCompare types rather than type names Pin
John Brett28-Oct-12 23:46
memberJohn Brett28-Oct-12 23:46 
AnswerRe: Compare types rather than type names Pin
Shahriar Iqbal Chowdhury29-Oct-12 2:34
memberShahriar Iqbal Chowdhury29-Oct-12 2:34 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.170113.4 | Last Updated 29 Oct 2012
Article Copyright 2012 by Shahriar Iqbal Chowdhury/Galib
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid