It's Spann, not spam

Technical blog to provide content that developers find useful.

Exporting Binary Files Inside SharePoint WebPart

Exporting Binary Files Inside SharePoint WebPart

  • Comments 7

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.

Technorati Tags: ,,
  • Hi,

    The above code works in MOSS 2007 version, but gives an error in Sharepoint 2010.

    The error is on line -

    var returnVal = beforeFormSubmitFunction();

    Any guess why it is? (The error is object expected. beforeFormSubmitFunction() is not being found)

    Thanks

  • I will look into this.  My guess is the issue with javascript in MOSS 2007 was fixed or changed.

  • Hye,

    I have the same problem as Hari.

    Is there a solution?

    Thanks

  • Try this for SP 2010:

    Page.ClientScript.RegisterStartupScript(this.GetType(), "_SPbypass", "_spSuppressFormOnSubmitWrapper = true;", true);

  • Thanks IP! That solved the problem in SP2010 for me!

  • I get following error:

    System.IO.IOException: The directory name is invalid.    

    at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)    

    at System.IO.Path.GetTempFileName()    

    at DevExpress.XtraExport.XlsxPackage.FileStreamProvider.CreateStream()    

    at DevExpress.XtraExport.XlsxPackage.FileStreamProvider..ctor()    

    at DevExpress.XtraExport.XlsxPackage.StreamProviderCreator.get_CanUseFileStream()    

    at DevExpress.XtraExport.XlsxPackage.StreamProviderCreator.Create()    

    at DevExpress.XtraExport.XlsxPackage.AddToArchive(ZipArchive archive, String path, XmlNode node)    

    at DevExpress.XtraExport.XlsxPackage.CreateXlsxFile()    

    at DevExpress.XtraExport.ExportXlsxProvider.DevExpress.XtraExport.IExportProvider.Commit()    

    at DevExpress.XtraPrinting.Export.XLS.XlsExportProviderBase.CreateDocument(LayoutControlCollection layoutControls, Boolean correctImportBrickBounds)    

    at DevExpress.XtraPrinting.PrintingSystemBase.ExportToXlsCore(XlsExportProviderBase xlsExportProvider)    

    at DevExpress.XtraPrinting.PrintingSystemBase.ExportToXlsx(Stream stream, XlsxExportOptions options)    

    at DevExpress.Web.ASPxGridView.Export.ASPxGridViewExporter.WriteXlsxCore(Stream stream, ExportOptionsBase exportOptions)    

    at DevExpress.Web.ASPxGridView.Export.ASPxGridViewExporter.WriteToResponse(String fileName, Boolean saveAsFile, String fileFormat, ExportToStream getStream, ExportOptionsBase options)    

    at DevExpress.Web.ASPxGridView.Export.ASPxGridViewExporter.WriteXlsxToResponse(String fileName)    

    at Medicinski_Falkultet.Layouts.Medicinski_Falkultet.Forms.ZgradaGrid.OnPreRender(EventArgs e)    

    at System.Web.UI.Control.PreRenderRecursiveInternal()    

    at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)

  • Page.ClientScript.RegisterStartupScript(this.GetType(), "_SPbypass", "_spSuppressFormOnSubmitWrapper = true;", true);

    this fixed the problem even in the 2007 thank you so much...

Page 1 of 1 (7 items)
Leave a Comment
  • Please add 6 and 8 and type the answer here:
  • Post