ahsteele
ahsteele

Reputation: 26514

Why do spaces in a file name cause IE to remove a file extension on file download?

I am using EPPlus to create an Excel file from a CSV which works without issue. Unfortunately, the below code causes Internet Explorer 9, 10, and 11 to drop the .xlsx file extension, while Chrome and Firefox do not. If I remove the spaces from the file name the file extension works as expected in IE.

public FileStreamResult DetailsExcel(string id)
{
    string custName;
    var csv = this.GetCsvForCustomer(id, out custName);
    var fileName = String.Format("Report for {0} ({1:d-M-yyyy HH mm})",
        custName, DateTime.Now);

    MemoryStream stream;

    using (var excelPackage = new ExcelPackage())
    {
        var ws = excelPackage.Workbook.Worksheets.Add(fileName);
        ws.Cells["A1"].LoadFromText(csv, this._excelTextFormat);
        stream = new MemoryStream(excelPackage.GetAsByteArray());
    }

    return File(stream,
        "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
        fileName + ".xlsx");
}

The two programmatic mechanisms that I have found that somewhat work are to wrap the file name in quotes or to UrlEncode the string. Each have issues:

String.Format("\"{0}\".xlsx", fileName)
// above renders: __Report for Customer (20-2-2014 11 04)__.xlsx

HttpUtility.UrlEncode(fileName + ".xlsx")
// above renders: Report+for+Customer+(20-2-2014+11+04).xlsx

Neither of the above are optimal. How do I include spaces in a file name without losing the file extension when a user is browsing with IE?

Upvotes: 4

Views: 821

Answers (1)

Steven V
Steven V

Reputation: 16595

I haven't been able to reproduce the behavior you describe in a similar application that I have. The only difference is that I'm not loading the byte array into a MemoryStream first, but just passing the byte array to File.

So try removing the MemoryStream from the equation. So the code would end up something like:

public ActionResult DetailsExcel(string id)
{
    byte[] stream;  // changed to byte array

    using (var excelPackage = new ExcelPackage())
    {
        var ws = excelPackage.Workbook.Worksheets.Add(fileName);
        ws.Cells["A1"].LoadFromText(csv, this._excelTextFormat);
        stream = excelPackage.GetAsByteArray();  // removed MemoryStream
    }

    return File(stream,
        "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
        fileName + ".xlsx");
}

Upvotes: 0

Related Questions