Sunday, March 8, 2009

Export Generic List To Excel File in Asp.net

In this post we will go throw a small example and very simple code export List of Employees to Excel File using StringWriter and HtmlTextWriter.
First i think we need to create a simple Employee Class:

   1: public class Employee
   2: {
   3:     public Employee(int age , string name )
   4:     {
   5:         this.Age = age;
   6:         this.Name = name; 
   7:     }
   8:     int _Age;
   9:     public int Age { get { return _Age; } set { _Age = value; } }
  10:     string _Name;
  11:     public string Name { get { return _Name; } set { _Name = value; } }
  12: }

second i will fill List of Employee Class with 3 employees and pass it to our Export method:

   1: protected void btnExportToExcel_Click(object sender, EventArgs e)
   2:    {
   3:        List<Employee> empList = new List<Employee>();
   4:        empList.Add(new Employee(20, "Ahmed"));
   5:        empList.Add(new Employee(23, "Mohamed"));
   6:        empList.Add(new Employee(30, "Ramy"));
   7: // take excel FileName and the Exported List 
   8:        Export("FileName", empList);
   9:    }

Discover Export method and read  its code comments:

   1: public void Export(string fileName, List<Employee> empList)
   2:     {
   3:         //The Clear method erases any buffered HTML output.
   4:         HttpContext.Current.Response.Clear();
   5:         //The AddHeader method adds a new HTML header and value to the response sent to the client.
   6:         HttpContext.Current.Response.AddHeader(
   7:             "content-disposition", string.Format("attachment; filename={0}", fileName + ".xls"));
   8:         //The ContentType property specifies the HTTP content type for the response.
   9:         HttpContext.Current.Response.ContentType = "application/ms-excel";
  10:         //Implements a TextWriter for writing information to a string. The information is stored in an underlying StringBuilder.
  11:         using (StringWriter sw = new StringWriter())
  12:         {
  13:             //Writes markup characters and text to an ASP.NET server control output stream. This class provides formatting capabilities that ASP.NET server controls use when rendering markup to clients.
  14:             using (HtmlTextWriter htw = new HtmlTextWriter(sw))
  15:             {
  16:                 //  Create a form to contain the List
  17:                 Table table = new Table();
  18:                 TableRow row = new TableRow();
  19:                 foreach (PropertyInfo proinfo in new Employee(1,"Name").GetType().GetProperties())
  20:                 {
  21:                     TableHeaderCell hcell = new TableHeaderCell();
  22:                     hcell.Text = proinfo.Name;
  23:                     row.Cells.Add(hcell);
  24:                 }
  25:                 table.Rows.Add(row);
  26:                 //  add each of the data item to the table
  27:                 foreach (Employee emp in empList)
  28:                 {
  29:                     TableRow row1 = new TableRow();
  30:                     TableCell cellAge = new TableCell();
  31:                     cellAge.Text = "" + emp.Age;
  32:                     TableCell cellName = new TableCell();
  33:                     cellName.Text = "" + emp.Name;
  34:                     row1.Cells.Add(cellAge);
  35:                     row1.Cells.Add(cellName);
  36:                     table.Rows.Add(row1);
  37:                 }
  38:                 //  render the table into the htmlwriter
  39:                 table.RenderControl(htw);
  40:                 //  render the htmlwriter into the response
  41:                 HttpContext.Current.Response.Write(sw.ToString());
  42:                 HttpContext.Current.Response.End();
  43:             }
  44:         }
  45:     }

Please if you have free time make this example more generic for me :) .

12 comments:

  1. Thank you, good work. It is very helpfull code for me.
    ReplyDelete
  2. Since its using Httpcontext, do you have an alternative code for winforms?
    ReplyDelete
  3. It would be nice if your code could be copied with a click... I believe that component has a way to enable this :)
    ReplyDelete
  4. @Nunez: sorry actually i don't have an alternative for windows but I'll search for this solution and publish it
    ReplyDelete
  5. @Anonymous2 : sure I'll search for this but if you have any component or script enable it please share .
    ReplyDelete
  6. i get following error while running above code

    Unable to evaluate expression because the code is optimized or a native frame is on top of the call stack.
    ReplyDelete
  7. Thank you very much good post.
    ReplyDelete
  8. Hi, Great post.
    I used PropertyInfo GetVale(T, null) to make it more generic. Here is the code:

    foreach (System.Reflection.PropertyInfo proinfo in list[0].GetType().GetProperties())
    {
    TableHeaderCell hcell = new TableHeaderCell();
    hcell.Text = proinfo.Name;
    string valueOfProp = proinfo.GetValue(list[0], null).ToString();
    row.Cells.Add(hcell);
    }
    table.Rows.Add(row);
    // add each of the data item to the table
    foreach (PromoCode code in list)
    {
    TableRow row1 = new TableRow();
    foreach (System.Reflection.PropertyInfo prop in code.GetType().GetProperties())
    {
    TableCell cell = new TableCell();
    cell.Text = prop.GetValue(code, null).ToString();
    row1.Cells.Add(cell);
    }
    table.Rows.Add(row1);
    }
    ReplyDelete
  9. Nice post about generic list.
    ReplyDelete
  10. Thanks for the code snippet! helped me - a simple copy-paste worked :)
    ReplyDelete
  11. Thanks for the code. It works fine for me. But when the user open file, it shows a message 'the file you are trying to open is in a different format than specified by the file extension. Verify that the file is not corrupted and is from a trusted source before opening the file'.
    How can I remove this message!
    ReplyDelete