Thursday, May 30, 2013

Nettiers Gridview Export to Excel

So, I'm trying to get (back) into the habit of posting information that I found to be helpful and this post is going to address an issue with exporting gridview contents to Excel.  In particular, I was using nettiers EntityGridView and getting a RegisterForEventValidation error when clicking the export link, but the same could apply to a regular gridview as well I think.  I didn't want to turn off event validation and leave a security hole (as I did have user input fields on the page) and was looking for another way to work around this.  We were using .netTiers v2.3.0.807 and I didn't want to mess with the template file so I found a way to handle it in the aspx page that contained the control.

Nettiers provides an event that gets called prior to the export called OnExcelBeforeFormat as well as after the export called OnExcelAfterFormat.  Our gridview used sorting, paging, and had checkboxes in some columns. 

By using this code, I was able to avoid the issue without turning off event validation or messing with the template...

///
/// Replace any of the contained controls with literals
///
///
private static void PrepareControlForExport(Control control)
{
  for (int i = 0; i < control.Controls.Count; i++)
  {
      Control current = control.Controls[i];
      if (current is LinkButton)
     {
        control.Controls.Remove(current);
        control.Controls.AddAt(i, new LiteralControl((current as LinkButton).Text));
      }
      else if (current is ImageButton)
      {
        control.Controls.Remove(current);
        control.Controls.AddAt(i, new LiteralControl((current as ImageButton).AlternateText));
      }
      else if (current is HyperLink)
      {
        control.Controls.Remove(current);
        control.Controls.AddAt(i, new LiteralControl((current as HyperLink).Text));
      }
      else if (current is DropDownList)
      {
        control.Controls.Remove(current);
        control.Controls.AddAt(i, new LiteralControl((current as DropDownList).SelectedItem.Text));
      }
      else if (current is CheckBox)
      {
        control.Controls.Remove(current);
        control.Controls.AddAt(i, new LiteralControl((current as CheckBox).Checked ? "True" : "False")) ;
      }
      if (current.HasControls())
      {
         PrepareControlForExport(current);
       }

   }
}



protected void GridView_OnExcelBeforeFormat(object sender, EventArgs e)
{
     PrepareControlForExport(GridView);
}

You will need to specify this event name for the OnExcelAfterFormat property of the EntityGridView.  This method could also be used with a standard Gridview just prior to any other export code.

One other thing that I found is that the gridview did not export the filtered results.  So, for this I added a piece of code to rebind the search parameters.

On Page_Load when IsPostback = true

//if export link clicked

if (Request.Params.Get("__EVENTTARGET").Contains("lnkExport"))
{
     //make sure to rebind search params
     GridViewSearchPanel.DataBind();
}

Hope someone else finds this helpful!