2

I am attempting to export a datagrid to excel via a popup. I am able to successfully export to excel when removing the code from my application, however, when attempting to export to excel using the exact same code within my application, I receive the following errors:

From my try/catch:

Unable to evaluate expression because the code is optimized or a native frame is on top of the call stack.

...and from the console:

Error: Sys.WebForms.PageRequestManagerParserErrorException: The message received from the server could not be parsed.

My server-side code is as follows:

protected void btnExportToExcel_Click(object sender, EventArgs e)
    {
        ExportDataSetToExcel();
    }

private void ExportDataSetToExcel()
    {

        try
        {
            DataTable dt = new DataTable("GridView_Data");
            foreach (TableCell cell in gvPatientRoster.HeaderRow.Cells)
            {
                dt.Columns.Add(cell.Text);
            }
            foreach (GridViewRow row in gvPatientRoster.Rows)
            {
                dt.Rows.Add();
                for (int i = 0; i < row.Cells.Count; i++)
                {
                    dt.Rows[dt.Rows.Count - 1][i] = row.Cells[i].Text;
                }
            }
            if (dt != null && dt.Rows.Count > 0)
            {
                Response.ContentType = "application/vnd.ms-excel";
                Response.AppendHeader("Content-Disposition",
                    string.Format("attachment; filename=PatientRoster.xls"));

                System.IO.StringWriter tw = new System.IO.StringWriter();
                System.Web.UI.HtmlTextWriter hw =
                    new System.Web.UI.HtmlTextWriter(tw);
                DataGrid dgGrid = new DataGrid();
                dgGrid.DataSource = dt;

                //Report Header
                hw.WriteLine("<b><u><font size='5'>" +
                             "Patient Roster</font></u></b>");
                hw.WriteLine("<br><br>");
                //hw.Write(BuildCriteriaString());
                hw.WriteLine("<br>");
                // Get the HTML for the control.
                dgGrid.HeaderStyle.Font.Bold = true;
                dgGrid.DataBind();
                dgGrid.RenderControl(hw);

                // Write the HTML back to the browser.

                this.EnableViewState = false;
                Response.Write(tw.ToString());
                Response.End();
            }
        }
        catch (Exception ex)
        {
            lblErrorMessage.Text = ex.Message;
        }

    }
MTL323
  • 177
  • 3
  • 14
  • 1
    Fair warning: setting the content-disposition header is not sufficient to force the file to be rendered as an Excel file. You'll need to use an API to write to the Excel file format, or export as CSV. Either way you will need to write the text to a file stream before returning it. – maniak1982 May 26 '15 at 14:29
  • Do you have a working example of this type of workflow? I have tried creating an Excel workbook using OpenXML. The file is created successfully locally, however, I run into issues when using this method from a web server. I could post the text being returned from the datagrid if that helps. – MTL323 May 26 '15 at 14:33
  • Exporting to CSV was answered previously on Stackoverflow. It's what I used last time someone requested an export. I wouldn't know how to help you with the OpenXML-generated worksheet without knowing the issues you saw. http://stackoverflow.com/questions/8530655/export-a-list-of-table-to-csv-file – maniak1982 May 26 '15 at 14:36
  • "I am able to successfully export to excel when removing the code from my application, however, when attempting to export to excel using the exact same code within my application, I receive the following errors" <-- What do you mean by this sentence? – user469104 May 26 '15 at 14:45
  • I have 2 solutions, one has only one webform that's function is to export a datagrid to excel, the other is a full web application with over 50 webforms where I, ultimately want this functionality to reside. I created the second solution to isolate the issue to ensure that my code was accurate and working (which it does when isolated). When this functionality is integrated into the main application, it throws the errors mentioned above. – MTL323 May 26 '15 at 15:27
  • I changed my code to use what was in the Export to CSV example. Just like with the original code, when isolated to its own solution, the functionality works properly, however, when integrated to the main application, the same errors mentioned above are thrown. – MTL323 May 26 '15 at 15:28
  • possible duplicate of [Sys.WebForms.PageRequestManagerParserErrorException: The message received from the server could not be parsed](http://stackoverflow.com/questions/11221033/sys-webforms-pagerequestmanagerparsererrorexception-the-message-received-from-t) – Johnny Bones Sep 08 '15 at 19:41

2 Answers2

0

I added the following to the PageLoad() and the export now works:

ScriptManager scriptManager = ScriptManager.GetCurrent(this.Page);
scriptManager.RegisterPostBackControl(this.btnExportToExcel);

It looks like the UpdatePanel and ScriptManager were elements that I overlooked. When I separated the functionality from the main application, I did not include all HTML that was in the main application. Since the ScriptManager and UpdatePanel were not part of the isolated functionality, it worked properly. I will be sure to post the HTML next time

This was a solution from the following post:

Sys.WebForms.PageRequestManagerParserErrorException: The message received from the server could not be parsed

Community
  • 1
  • 1
MTL323
  • 177
  • 3
  • 14
0

I would suggest using one of the many good, free C# "Export to Excel" libraries out there.

You've already written the code to read your DataView into a DataTable, and once it's in this format, using the following free C# library...

ExportToExcel library

...you'd be able to export the data into a "real" Excel 2007 file in one line of code....

//  Export the DataTable into an Excel file, and write it to the web Response
CreateExcelFile.CreateExcelDocument(dt, "SomeFilename.xlsx", Response);

Okay, okay, two lines of code. I added a comment.

But you get the point !

Mike Gledhill
  • 27,846
  • 7
  • 149
  • 159