0

I want to export data from GridView into an excel file on ASP.NET website. I added a GridView only for this purpose

<body>
   <form id="mainForm" runat="server">
      <asp:GridView ID="exportGrid" runat="server">
      </asp:GridView>
   </form>
....
</body>

In codebehind I have this:

public override void VerifyRenderingInServerForm(Control control) { }

var result = GetDataIQueryable(); //A method that returns an IQueryable
exportGrid.DataSource = result; 
exportGrid.DataBind();
Response.Clear();
Response.ClearContent();
Response.AddHeader("content-disposition", "attachment; filename=" + "ExcelFile.xls");
Response.ContentType = "application/excel";
var sw = new System.IO.StringWriter();
var htw = new HtmlTextWriter(sw);
exportGrid.RenderControl(htw);
Response.Write(sw.ToString());
Response.End();

The problem is that the popup that allows me to save the excel file on my computer is not appearing. What should I change in my code ?

dpv
  • 177
  • 1
  • 2
  • 9

2 Answers2

1

Use this code on your button click event

 protected void btnExport_Click(object sender, EventArgs e)
{
    Response.Clear();
    Response.Buffer = true;
    Response.AddHeader("content-disposition", "attachment;filename=FormReport.xls");
    Response.Charset = "";
    Response.ContentType = "application/vnd.ms-excel";
    using (StringWriter sw = new StringWriter())
    {
        HtmlTextWriter hw = new HtmlTextWriter(sw);

        //To Export all pages
        GridView1.AllowPaging = false;            
        BindGridView();

        GridView1.HeaderRow.BackColor = Color.White;
        foreach (TableCell cell in GridView1.HeaderRow.Cells)
        {
            cell.BackColor = GridView1.HeaderStyle.BackColor;
        }
        foreach (GridViewRow row in GridView1.Rows)
        {
            row.BackColor = Color.White;
            foreach (TableCell cell in row.Cells)
            {
                if (row.RowIndex % 2 == 0)
                {
                    cell.BackColor = GridView1.AlternatingRowStyle.BackColor;
                }
                else
                {
                    cell.BackColor = GridView1.RowStyle.BackColor;
                }
                cell.CssClass = "textmode";
            }
        }

        GridView1.RenderControl(hw);

        //style to format numbers to string
        string style = @"<style> .textmode { } </style>";
        Response.Write(style);
        Response.Output.Write(sw.ToString());
        Response.Flush();
        Response.End();
        GridView1.Dispose();
    }
}
#endregion

public override void VerifyRenderingInServerForm(Control control)
{
    /* Verifies that the control is rendered */
}

and on .aspx page use

 <%@ Page Title="" Language="C#" EnableEventValidation="false"%>
amitesh
  • 766
  • 5
  • 17
  • 39
  • The same problem. I don't get any errors but the popup is not appearing so I can't save the excel file. – dpv Nov 19 '13 at 10:43
  • are you using that code on click event of your Export button. – amitesh Nov 19 '13 at 10:45
  • Yes is in click event method. I've found this problem in your code (http://stackoverflow.com/questions/2041482/unable-to-evaluate-expression-because-the-code-is-optimized-or-a-native-frame-is ) with Response.End() after correction is still not working. – dpv Nov 19 '13 at 11:16
  • Yes, is set to false. – dpv Nov 19 '13 at 11:46
  • you use public override void VerifyRendringInServerForm(Control control){} – amitesh Nov 19 '13 at 11:49
  • Yes, I'm using that too. After GridView1.Dispose(); nothing happends, no error or nothing. – dpv Nov 19 '13 at 23:39
  • then don't dipose your gridview remove that link and then use – amitesh Nov 20 '13 at 08:39
  • The GridView was in an UpdatePanel and triggers for buttons should be added. Now is working with your code. Thanks – dpv Nov 20 '13 at 16:33
1

I know this is a bit too late, but i am posting this just for information. I found the answer in the comments but i would still like to submit a answer with code , because i myself found it difficult to find the code so the answer is for if your grid is inside update panel. You need to add a post back trigger to the button.

  private void RegisterPostBackControl()
    {
        ScriptManager.GetCurrent(this).RegisterPostBackControl(yourButton);
    }


    public override void VerifyRenderingInServerForm(Control control)
    {
        /* Verifies that the control is rendered */
    }

Your Buttons Click Event :

protected void yourButton_Click(object sender, EventArgs e)
    {

        ClientScript.RegisterClientScriptBlock(this.GetType(), "alert", "full", true);
        Response.Clear();
        Response.Buffer = true;
        Response.AddHeader("content-disposition", "attachment;filename=FormReport.xls");
        Response.Charset = "";
        Response.ContentType = "application/vnd.ms-excel";
        using (StringWriter sw = new StringWriter())
        {
            HtmlTextWriter hw = new HtmlTextWriter(sw);

            //To Export all pages
            yourGrid.AllowPaging = false;
            var emps = FunctionThatGetsGridValues();
            yourGrid.DataSource = emps;
            yourGrid.DataBind();

            yourGrid.HeaderRow.BackColor = Color.White;
            foreach (TableCell cell in yourGrid.HeaderRow.Cells)
            {
                cell.BackColor = yourGrid.HeaderStyle.BackColor;
            }
            foreach (GridViewRow row in yourGrid.Rows)
            {
                row.BackColor = Color.White;
                foreach (TableCell cell in row.Cells)
                {
                    if (row.RowIndex % 2 == 0)
                    {
                        cell.BackColor = yourGrid.AlternatingRowStyle.BackColor;
                    }
                    else
                    {
                        cell.BackColor = yourGrid.RowStyle.BackColor;
                    }
                    cell.CssClass = "textmode";
                }
            }

            yourGrid.RenderControl(hw);

            //style to format numbers to string
            string style = @"<style> .textmode { } </style>";
            Response.Write(style);
            Response.Output.Write(sw.ToString());
            Response.Flush();
            Response.End();
            yourGrid.Dispose();
        }
    }

And On Page Load Dont forget to add :

  protected void Page_Load(object sender, EventArgs e)
    {
        this.RegisterPostBackControl();
    }
Devanshi Parikh
  • 265
  • 4
  • 12