Daniel Hoelbling-Inzko talks about programming

Exporting Data to CVS in ASP.NET

Posted by Daniel Hölbling on June 16, 2008

So, today I tried the ASP.NET Wiki that's currently in Beta and thought, best way to do so is to expand an article. I'll blog about my Wiki experience later, but for now I'd like to share my code on this one.

I started out with the Wiki Article Export to CSV file (revision 3) and thought on how to improve it.

As you may have noticed, the topic at hand is so simple, it doesn't really need improving, except for the main flaw where you have to specify all column headers in code.

My take on this was to use the DataBinder API from the System.Web.UI namespace and remove the whole HttpContext.Current stuff to an instance variable so it's easier to test the stuff and you can put it into a class library (if you want that).

Let's assume I have a list of type Person I want to write to CSV

public class Person
    public String Name
    { get; set; }
    public String Family
    { get; set; }
    public int Age
    { get; set; }
    public decimal Salary
    { get; set; }

Now here's the CVSExporter class that you just need to pass 3 things: Your List<Person>, your HttpContext.Current and a List<String> that specifies what columns you want printed out (eg. Name, Family).

public class CSVExporter
    public static void WriteToCSV(List<Object> dataList, HttpContext httpContext, List<String> columnNames)

        WriteColumnNames(httpContext, columnNames);                  foreach (Object data in dataList)         {             WriteData(data, httpContext, columnNames);         }                  httpContext.Response.End(); //Everything has to end..     }

    private static void InitializeHeaders(HttpContext httpContext)     {         string attachment = "attachment; filename=PersonList.csv";         httpContext.Response.Clear();         httpContext.Response.ClearHeaders();         httpContext.Response.ClearContent();         httpContext.Response.AddHeader("content-disposition", attachment);         httpContext.Response.ContentType = "text/csv";         httpContext.Response.AddHeader("Pragma", "public");     }

    private static void WriteData(Object data, HttpContext httpContext, List<String> columnNames)     {         StringBuilder stringBuilder = new StringBuilder();         foreach (String column in columnNames)         {             AddComma(                 System.Web.UI.DataBinder.Eval(data, column).ToString(),                 stringBuilder);         }         httpContext.Response.Write(stringBuilder.ToString());         httpContext.Response.Write(Environment.NewLine);     }

    private static void AddComma(string value, StringBuilder stringBuilder)     {         stringBuilder.AppendFormat("{0}, ", value.Replace(',', ' '));     }

    private static void WriteColumnNames(HttpContext httpContext, List<String> columnNames)     {         StringBuilder stringBuilder = new StringBuilder();         foreach (String column in columnNames)         {             stringBuilder.AppendFormat("{0}, ", column);         }         httpContext.Response.Write(stringBuilder.ToString());         httpContext.Response.Write(Environment.NewLine);     }


So that's it for now. I guess there is still room for improvement, and if you need performance you should go with the original solution, DataBinder.Eval does some type-casting internally so it won't run at lightning speeds, but you get the idea of what can be done with the DataBinder control :).

And now I'm off to writing a Windows Live Writer Plugin that will allow me to paste longer code without jumping through loops like a madman (I posted the code in my Wordpress admin-gui because doing it from wlv simply didn't work!)

Filed under net, programmierung
comments powered by Disqus

My Photography business


dynamic css for .NET