Download file with ClosedXML

Tjekkles picture Tjekkles · Mar 10, 2014 · Viewed 41k times · Source

All

How can I download a file so the user sees that it is downloading (like with a stream?)

I am currently using ClosedXML, but if I use the SaveAs method, I have to give a hard-coded URL, and if I just give the file name it does not automatically download to the download folder.

The method below works great, but I have to create my own excel file, which is based upon HTML, and the file grows way too large than it should, when I use ClosedXML the file is only 50% or less from the size of the code below: However, the download behaviour is how I would like it to be.

Is there a way I can convert the code below so I can give my 'workbook' as an object, and it just downloads this workbook?

HttpContext.Current.Response.AppendHeader("Content-Disposition","attachment;filename=Excel.xls");
HttpContext.Current.Response.Charset ="UTF-8";    
HttpContext.Current.Response.ContentEncoding=System.Text.Encoding.Default;
HttpContext.Current.Response.ContentType = "application/ms-excel";
ctl.Page.EnableViewState =false;   
System.IO.StringWriter  tw = new System.IO.StringWriter() ;
System.Web.UI.HtmlTextWriter hw = new System.Web.UI.HtmlTextWriter (tw);
ctl.RenderControl(hw);
HttpContext.Current.Response.Write(tw.ToString());
HttpContext.Current.Response.End();

Thanks

Answer

Raidri supports Monica picture Raidri supports Monica · Mar 10, 2014

The SaveAs() method supports stream, so to get the ClosedXml workbook as a stream I use:

public Stream GetStream(XLWorkbook excelWorkbook)
{
    Stream fs = new MemoryStream();
    excelWorkbook.SaveAs(fs);
    fs.Position = 0;
    return fs;
}

And then for downloading the file:

string myName = Server.UrlEncode(ReportName + "_" + DateTime.Now.ToShortDateString() + ".xlsx");
MemoryStream stream = GetStream(ExcelWorkbook);

Response.Clear();
Response.Buffer = true;
Response.AddHeader("content-disposition", "attachment; filename=" + myName);
Response.ContentType = "application/vnd.ms-excel";
Response.BinaryWrite(stream.ToArray());
Response.End();