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 ?
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"%>
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();
}
Related
I have a User control which contains data , basically like questions and answers (with yes or no options). Now I want to export the entire data from the User control to Excel sheet on clicking a button. How can I achieve this?
Any suggestions would be highly appreciated.
Here is my code that I use to do it.
public class ExcelUtility
{
public static void ToExcel(object dataSource)
{
GridView grid = new GridView { DataSource = dataSource };
grid.DataBind();
StringBuilder sb = new StringBuilder();
foreach (TableCell cell in grid.HeaderRow.Cells)
sb.Append(string.Format("\"{0}\",", cell.Text));
sb.Remove(sb.Length - 1, 1);
sb.AppendLine();
foreach (GridViewRow row in grid.Rows)
{
foreach (TableCell cell in row.Cells)
sb.Append(string.Format("\"{0}\",", cell.Text.Trim().Replace(" ", string.Empty)));
sb.Remove(sb.Length - 1, 1);
sb.AppendLine();
}
ExportToExcel(sb.ToString());
}
private static void ExportToExcel(string data)
{
HttpContext.Current.Response.Clear();
HttpContext.Current.Response.AddHeader("content-disposition", "attachment;filename=Report.csv");
HttpContext.Current.Response.ContentEncoding = System.Text.Encoding.GetEncoding("windows-1255");
HttpContext.Current.Response.ContentType = "text/csv";
HttpContext.Current.Response.Write(data);
HttpContext.Current.Response.End();
}
}
You will have to create a structure containing table tr and td and then you can export it to excel.
Other wise if you have a datatable or collection like source only then you can export it to excel.
You will have to write function to change your user-control to collection and then you can export it to excel.
Here is a sample code
<table id="mytable" runat="server">
<tr ><td>1</td></tr>
<tr><td>2</td></tr>
</table>
<asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Button" />
protected void Button1_Click(object sender, EventArgs e)
{
Response.Clear();
Response.AddHeader("content-disposition","attachment;filename=myexcel.xls");
Response.ContentType = "application/ms-excel";
System.IO.StringWriter sw = new System.IO.StringWriter();
System.Web.UI.HtmlTextWriter hw = new HtmlTextWriter(sw);
mytable.RenderControl(hw);
Response.Write(sw.ToString());
Response.End();
}
public override void VerifyRenderingInServerForm(Control control)
{
}
I have Gridview and I have three options to export the data to excel sheet:
current page
all pages
top100 row
It worked will with current but the other options didn't work.
Code:
protected void btnExportGrid_Click(object sender, EventArgs e)
{
Table table = new Table
{
GridLines = this.gv_RquestedOrdres.GridLines
};
if (this.rdoBtnListExportOptions.SelectedIndex == 1)
{
this.gv_RquestedOrdres.AllowPaging = false;
this.gv_RquestedOrdres.DataBind();
}
else if (this.rdoBtnListExportOptions.SelectedIndex == 2)
{
this.gv_RquestedOrdres.PageSize = 100;
this.gv_RquestedOrdres.DataBind();
}
GridViewExportUtil.Export("Orders.xls", this.gv_RquestedOrdres);
}
private string Gridview(Panel gv)
{
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
HtmlTextWriter hw = new HtmlTextWriter(sw);
gv.RenderControl(hw);
return sb.ToString();
}
GridViewExportUtil class:
public class GridViewExportUtil
{
public static void Export(string fileName, GridView gv)
{
HttpContext.Current.Response.Clear();
HttpContext.Current.Response.AddHeader("content-disposition", string.Format("attachment; filename={0}", fileName));
HttpContext.Current.Response.ContentType = "application/ms-excel";
HttpContext.Current.Response.ContentEncoding = System.Text.Encoding.Unicode;
HttpContext.Current.Response.BinaryWrite(System.Text.Encoding.Unicode.GetPreamble());
using (StringWriter writer = new StringWriter())
{
using (HtmlTextWriter writer2 = new HtmlTextWriter(writer))
{
Table table = new Table();
if (gv.HeaderRow != null)
{
PrepareControlForExport(gv.HeaderRow);
table.Rows.Add(gv.HeaderRow);
}
foreach (GridViewRow row in gv.Rows)
{
PrepareControlForExport(row);
table.Rows.Add(row);
}
if (gv.FooterRow != null)
{
PrepareControlForExport(gv.FooterRow);
table.Rows.Add(gv.FooterRow);
}
table.RenderControl(writer2);
HttpContext.Current.Response.Write(writer.ToString());
HttpContext.Current.Response.End();
}
}
}
private static void PrepareControlForExport(Control control)
{
for (int i = 0; i < control.Controls.Count; i++)
{
Control control2 = control.Controls[i];
if (control2 is LinkButton)
{
control.Controls.Remove(control2);
control.Controls.AddAt(i, new LiteralControl((control2 as LinkButton).Text));
}
else if (control2 is ImageButton)
{
control.Controls.Remove(control2);
control.Controls.AddAt(i, new LiteralControl((control2 as ImageButton).AlternateText));
}
else if (control2 is HyperLink)
{
control.Controls.Remove(control2);
control.Controls.AddAt(i, new LiteralControl((control2 as HyperLink).Text));
}
else if (control2 is DropDownList)
{
control.Controls.Remove(control2);
control.Controls.AddAt(i, new LiteralControl((control2 as DropDownList).SelectedItem.Text));
}
else if (control2 is CheckBox)
{
control.Controls.Remove(control2);
control.Controls.AddAt(i, new LiteralControl((control2 as CheckBox).Checked ? "True" : "False"));
}
if (control2.HasControls())
{
PrepareControlForExport(control2);
}
}
}
}
You are using grid-view for exporting the data - it only means that current page of grid-view would be rendered into exported html. To render complete data (or top 100 rows), set your page size accordingly. So Page size of 100 rows with page index of 1 would give you top 100 rows export while disabling paging should give you all pages - revert the paging once export is over.
Yet another alternative is to use the actual data (that you have bound to gird) to do a CSV export (can be opened in excel) (or do html export using Table and Row but instead of using grid-view rows, use data to add cells into html Row)
I implemented export to excel functionality in asp.net application.Here i export data from Grid-view to excel-sheet.I also applied Paging in Grid-view.
So when i export data from Grid-view to excel sheet,paging text also display in excel sheet as shown in the given image.
How can we remove it
i follow the below approach for exporting data
Code-Behind:
Response.Clear()
Response.ClearHeaders()
Response.AddHeader("content-disposition", "attachment;filename=sample.xls")
Response.Charset = ""
Response.ContentType = "application/vnd.xls"
Dim sb As StringBuilder = New StringBuilder()
Dim objStringWriter As StringWriter = New StringWriter(sb)
Dim objHtmlTextWriter As HtmlTextWriter = New HtmlTextWriter(objStringWriter)
//gvSample is Gridview server control
gvSample.RenderControl(objHtmlTextWriter)
Response.ContentEncoding = Encoding.Unicode
Response.BinaryWrite(System.Text.Encoding.Unicode.GetPreamble())
Response.Write(objStringWriter)
Response.End()
Thanks
Before rendering - disable the paging, bind the data and then render:
gvSample.AllowPaging = false;
gvSample.DataSource = ds; //Data Source
gvSample.DataBind();
gvSample.RenderControl(objHtmlTextWriter)
when ever to get the data from database for show the gridview,before that but the result content in viewstate[""] after the reuse it. when search the data for filter the main content the updated data will present in the viewstate, so you will get correct data to export
gvSample.AllowPaging = false;
gvSample.DataSource = ViewState["vsData"]; //Data Source
gvSample.DataBind();
gvSample.RenderControl(objHtmlTextWriter);
It works using SQL DataSourceID
using (StringWriter sw = new StringWriter())
{
HtmlTextWriter hw = new HtmlTextWriter(sw);
//To Export all pages
GridView1.AllowPaging = false;
GridView1.DataBind();
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 { mso-number-format:\#; } </style>";
Response.Write(style);
Response.Output.Write(sw.ToString());
Response.Flush();
Response.End();
other attached asp coding file
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
e.Row.Attributes["ondblclick"] = Page.ClientScript.GetPostBackClientHyperlink(GridView1, "Edit$" + e.Row.RowIndex);
e.Row.Attributes["style"] = "cursor:pointer";
}
}
Kindly help me on how to remove image in my excel header. I generate the excel using export command using gridview as source data
here is my code
Response.AddHeader("content-disposition", "attachment;filename=" & strFilename & ".xls")
Response.Clear()
Response.Charset = ""
Response.ContentType = "application/vnd.xls"
Dim sw As System.IO.StringWriter = New System.IO.StringWriter()
Dim htw As System.Web.UI.HtmlTextWriter = New System.Web.UI.HtmlTextWriter(sw)
grvData.AllowPaging = False
grvData.AllowSorting = False
PopulateGrid()
grvData.RenderControl(htw)
Response.Write(sw.ToString)
Response.End()
Everything was set -except that one my header had a blank header name because of the image that was now shown - the image is came from gridview (I'm using arrow for asc and desc) - sorry i cant post any image here now
Give this ClearControls method a shot. It should remove any controls from the Grid before exporting:
protected void btnExport_Click(object sender, EventArgs e)
{
Response.Clear();
Response.Buffer = true;
Response.ContentType = "application/vnd.ms-excel";
Response.Charset = "";
System.IO.StringWriter oStringWriter = new System.IO.StringWriter();
System.Web.UI.HtmlTextWriter oHtmlTextWriter = new System.Web.UI.HtmlTextWriter(oStringWriter);
this.ClearControls(DataGrid1);
DataGrid1.RenderControl(oHtmlTextWriter);
DataGrid1.GridLines = GridLines.Both;
DataGrid1.Style.Clear();
Response.Write(oStringWriter.ToString());
Response.End();
}
private void ClearControls(Control control)
{
for (int i = control.Controls.Count - 1; i >= 0; i--)
{
ClearControls(control.Controls[i]);
}
if (!(control is TableCell))
{
if (control.GetType().GetProperty("SelectedItem") != null)
{
LiteralControl literal = new LiteralControl();
control.Parent.Controls.Add(literal);
try
{
literal.Text = (string)control.GetType().GetProperty("SelectedItem").GetValue(control, null);
}
catch
{
//do nothing
}
finally
{
control.Parent.Controls.Remove(control);
}
}
else
{
if (control.GetType().GetProperty("Text") != null)
{
LiteralControl literal = new LiteralControl();
control.Parent.Controls.Add(literal);
literal.Text = (string)control.GetType().GetProperty("Text").GetValue(control, null);
control.Parent.Controls.Remove(control);
}
}
}
return;
}
protected void Button2_Click(object sender, EventArgs e)
{
Response.Clear();
Response.Buffer = true;
Response.AddHeader("content-disposition",
"attachment;filename=GridViewExport.doc");
Response.Charset = "";
Response.ContentType = "application/vnd.ms-word ";
StringWriter sw = new StringWriter();
HtmlTextWriter hw = new HtmlTextWriter(sw);
GridView1.AllowPaging = false;
GridView1.RenderControl(hw);
Response.Output.Write(sw.ToString());
Response.Flush();
Response.End();
}
public override void VerifyRenderingInServerForm(Control control)
{
/* Verifies that the control is rendered */
}
this is my code in the .cs file what am trying to do is export a gridview to word file
but when i run the code it gives an error
RegisterForEventValidation can only be called during Render();
pls help
Copying the answer from comment:
got the answer guys EnableEventValidation ="false" just have to add this in the page directive