Exporting Binary Files Inside SharePoint WebPart
So today I ran into an issue that has sure to have plagued the SharePoint developer community in the past. My requirement was to export data rendered in a grid to Excel. Seems simple enough.
So I have a DevExpress ASPxGridView control and a DevExpress ASPxGridViewExporter control inside my WebPart. Everything was working as expected. Here is the initial code:
1: protected void btnXlsExport_Click(object sender, EventArgs e)
2: { 3: DoDataBinding();
4: GridViewExporter.WriteXlsToResponse();
5: }
Deployed my WebPart and the trouble begins…
After spending half a day trying to figure out why my WebPart or for that matter, my Page would stop responding after I exported to Excel, I found a post that explained it so well. Basically the problem is with the javascript that SharePoint embeds into every page for you. SharePoint wants to make your life easier by protecting you from unnecessary double-posts. Well unfortunately that is the cause of the stream output rendering your page useless.
The fix:
First you need to add the following to your button’s ClientClick event.
<asp:Button ID="ExcelExport" runat="server" Text="Export to Excel" OnClick="btnXlsExport_Click"
CausesValidation="false" OnClientClick="exportRequested=true;" />
Second, you need to add the following code to the OnLoad event of the Page/Control.
private const string startupScriptKey = "alterFormSubmitEvent";
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
if(!this.Page.IsStartupScriptRegistered(startupScriptKey))
{
StringBuilder beforeSubmitJS = new StringBuilder();
beforeSubmitJS.Append("var beforeFormSubmitFunction = theForm.onsubmit; \n");
beforeSubmitJS.Append("theForm.onsubmit = function(){ \n");
beforeSubmitJS.Append("var returnVal = beforeFormSubmitFunction(); \n");
beforeSubmitJS.Append("if(exportRequested && returnVal)");
beforeSubmitJS.Append("{_spFormOnSubmitCalled=false; exportRequested=false;} \n");
beforeSubmitJS.Append("return returnVal; \n");
beforeSubmitJS.Append("}; \n");
this.Page.ClientScript.RegisterStartupScript(
this.GetType(),
startupScriptKey,
beforeSubmitJS.ToString(),
true);
}
}
Finally, deploy your WebPart to the SharePoint site. You now have a responsive page and exporting the binary files that your users wanted!
Many thanks go out to Michael Nemtsev and Andy Spears for the great work.