Search code examples
c#asp.netvb.netexport-to-excel

ASP.NET Downloading exported excel sheet sometimes renders the source page itselft


I have two reports that download excel files when the user clicks the export button. Both of them use the same method in an external library (shown below). One of the reports opens the excel sheet normally with the generated data while the other shows the source page design inside the excel sheet. This happens in VS2008. What is going on, and how to solve it?

            HttpContext.Current.Response.Clear();
            HttpContext.Current.Response.ClearContent();
            HttpContext.Current.Response.ClearHeaders();
            HttpContext.Current.Response.Buffer = true;
            HttpContext.Current.Response.ContentType = "application/ms-excel;";
            HttpContext.Current.Response.BinaryWrite(System.Text.Encoding.UTF8.GetPreamble());
            HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment;filename=Report.xls");
            HttpContext.Current.Response.Charset = "utf-8";
            HttpContext.Current.Response.ContentEncoding = System.Text.Encoding.UTF8;

            HttpContext.Current.Response.Write(@"<!DOCTYPE HTML PUBLIC ""-//W3C//DTD HTML 4.0 Transitional//EN"">");

            //sets font
            HttpContext.Current.Response.Write("<font style='font-size:10.0pt; font-family:Calibri;'>");

            if (addCurrentDate)
                HttpContext.Current.Response.Write("<h5 align='left'>" + DateTime.Now.ToString() + "</h5>");
            HttpContext.Current.Response.Write("<h2>" + title + "</h2>");

            string subttitlesString = string.Empty;
            if (subItems != null && subItems.Count > 0)
            {
                subttitlesString = "<table>";
                foreach (var item in subItems)
                {
                    subttitlesString += string.Format("<tr><td style='font-weight:bold;'>{0}</td><td>{1}</td></tr>", item.Key, item.Value);
                }
                subttitlesString += "</table>";
                HttpContext.Current.Response.Write(subttitlesString);
            }

            //sets the table border, cell spacing, border color, font of the text, background, foreground, font height
            HttpContext.Current.Response.Write("<Table border='1' bgColor='#ffffff' " +
              "borderColor='#000000' cellSpacing='0' cellPadding='0' " +
              "style='font-size:10.0pt; font-family:Calibri; background:white;'> <TR>");

            //am getting my grid's column headers
            int columnscount = table.Columns.Count;

            for (int j = 0; j < columnscount; j++)
            {      //write in new column
                HttpContext.Current.Response.Write("<Td>");
                //Get column headers  and make it as bold in excel columns
                HttpContext.Current.Response.Write("<B>");
                HttpContext.Current.Response.Write(table.Columns[j].ColumnName.ToString());
                HttpContext.Current.Response.Write("</B>");
                HttpContext.Current.Response.Write("</Td>");
            }

            HttpContext.Current.Response.Write("</TR>");
            foreach (DataRow row in table.Rows)
            {//write in new row
                HttpContext.Current.Response.Write("<TR>");
                for (int i = 0; i < table.Columns.Count; i++)
                {
                    HttpContext.Current.Response.Write("<Td>");
                    HttpContext.Current.Response.Write(row[i].ToString());
                    HttpContext.Current.Response.Write("</Td>");
                }

                HttpContext.Current.Response.Write("</TR>");
            }

            HttpContext.Current.Response.Write("</Table>");
            HttpContext.Current.Response.Write("</font>");
            HttpContext.Current.Response.Flush();
            HttpContext.Current.Response.End();

The excel sheet being exported:


Solution

  • I found the cause of this, which is quite obvious now. The calling event of the above exporting method has two catch sections:

    1. ThreadAbortException
    2. Exception

    The ThreadAbortException part had Thread.ResetAbort() because the ThreadAbortException keeps re-throwing itself. This seems to reset all the HTTPRespnse content that was previously added.