Marrs
Marrs

Reputation: 716

How to download a generated excel file from your asp.net application

I am building an asp.net website and I am constructing a Excel document based on some gridview data. I am using Microsoft.Office.Interop.Excel to construct it. I have tried to use a saveFileDialog box using System.Windows.Forms. Through my research online, I have learned that you can’t actually do this in an asp.net application? Everything works great in debugging mode, but when uploading it to the site, the page doesn't work at all. So my man question is, is it possible to to use a saveFileDialog box for an asp.net application? Does anyone know a good workaround for this? I will post my code that works great in debugging mode, but doesn't work when I upload it to my site. Thanks in advance for any help.

using System.Threading;
using Excel = Microsoft.Office.Interop.Excel;
using Microsoft.Office.Interop.Excel;
using System.Windows.Forms;

SaveFileDialog saveFileDialog1 = new SaveFileDialog();
Excel.Application xlApp = new Excel.Application();
Excel.Workbook xlWorkBook;
Excel.Worksheet xlWorkSheet;
object misValue = System.Reflection.Missing.Value;

public void someEvent()
{
    var t = new Thread(SaveFolder);
    t.IsBackground = true;
    t.SetApartmentState(ApartmentState.STA);
    t.Start();
}

public void SaveFolder()
{
    saveFileDialog1.Filter = "Sources (*.xls, *.xlsx)|*.xls*;*.xlsx"; 
    saveFileDialog1.ShowDialog();
    exportReport();
}

public void exportReport()
{
    xlWorkBook.SaveAs(@saveFileDialog1.FileName, Excel.XlFileFormat.xlWorkbookNormal, misValue, misValue, misValue, misValue, Excel.XlSaveAsAccessMode.xlExclusive, misValue, misValue, misValue, misValue, misValue);
    xlWorkBook.Close(true, misValue, misValue);
    xlApp.Quit();

    releaseObject(xlApp);
    releaseObject(xlWorkBook);
    releaseObject(xlWorkSheet);
}

public void releaseObject(object obj)
{
    try
    {
        System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
        obj = null;
    }
    catch (Exception ex)
    {
        obj = null;
        MessageBox.Show("Unable to release the Object " + ex.ToString());
    }
    finally
    {
        GC.Collect();
    }
} 

Upvotes: 1

Views: 7230

Answers (3)

Cᴏʀʏ
Cᴏʀʏ

Reputation: 107508

You can't do what you want to with the save dialog. You should just save the file to a temporary location on your server. Once you have the file saved somewhere, you can force the file at the user for download. I usually follow this code (seems to work in all browsers the most consistently). You have to supply the filename and yourFileByteArray variables.

Response.Buffer = true;
Response.Clear();
Response.ClearHeaders();
Response.ContentType = "application/vnd.ms-excel";
Response.CacheControl = "public";
Response.AddHeader("Pragma", "public");
Response.AddHeader("Expires", "0");
Response.AddHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0");
Response.AddHeader("Content-Description", "Excel File Download");
Response.AddHeader("Content-Disposition", "attachment; filename=\"" + filename + "\"");

Response.BinaryWrite(yourFileByteArray);
Response.Flush();
Response.End();

There are several ways to get your file as a byte array, but I'll leave that as an exercise for you.

Upvotes: 2

p.campbell
p.campbell

Reputation: 100567

Don't use Interop. Suggest using a mix of HtmlTextWriter, StringWriter, and your GridView.

public void GridViewToExcel()
{
    Response.Clear();
    Response.AddHeader("content-disposition", "attachment;filename=MyFile.xls");
    Response.Charset = "";
    Response.ContentType = "application/vnd.xls";

    var writer = new System.IO.StringWriter();
    var htmlWriter = new HtmlTextWriter(writer);

    GridView1.RenderControl(htmlWriter);
    Response.Write(writer.ToString());
    Response.End();
}

Upvotes: 1

Joel Spolsky
Joel Spolsky

Reputation: 33647

You can't show a dialog box on the server. There's nobody there to see it. Get rid of the whole saveFileDialog object and just call SaveAs with a generated filename in the server's file system that is guaranteed to be unique. Then transmit that file to your user.

Upvotes: 0

Related Questions