Создание файла Excel с EPPlus не выполняется
Когда я пытаюсь сгенерировать файл Excel с помощью EPPlus, Excel сообщит мне следующее сообщение об ошибке:
Excel не может открыть файл 'myfilename.xlsx', потому что формат файла или расширение файла недействительны. Убедитесь, что файл не был поврежден и расширение файла соответствует формату файла.
Здесь мой код:
public ActionResult Index()
{
using (ExcelPackage package = new ExcelPackage())
{
// I populate the worksheet here. I'm 90% sure this is fine
// because the stream file size changes based on what I pass to it.
var stream = new MemoryStream();
package.SaveAs(stream);
string fileName = "myfilename.xlsx";
string contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
var cd = new System.Net.Mime.ContentDisposition
{
Inline = false,
FileName = fileName
};
Response.AppendHeader("Content-Disposition", cd.ToString());
return File(stream, contentType, fileName);
}
}
Любая идея, что я делаю неправильно?
Ответы
Ответ 1
Все, что вам нужно сделать, это reset позиция потока. stream.Position = 0;
Вы не должны писать непосредственно в Response, это не путь MVC. Он не соответствует правильному конвейеру MVC и плотно соединяет ваш код действия контроллера с объектом Response.
Когда вы добавляете имя файла в качестве 3-го параметра в File()
, MVC автоматически добавляет правильный заголовок Content-Disposition
... поэтому вам не нужно добавлять его вручную.
Короче говоря, это то, что вы хотите:
public ActionResult Index()
{
using (ExcelPackage package = new ExcelPackage())
{
// I populate the worksheet here. I'm 90% sure this is fine
// because the stream file size changes based on what I pass to it.
var stream = new MemoryStream();
package.SaveAs(stream);
string fileName = "myfilename.xlsx";
string contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
stream.Position = 0;
return File(stream, contentType, fileName);
}
}
Ответ 2
Ваш код не показывает stream
, который записывается в HttpResponse
, предположительно выполняемый в методе File
, который вы еще не отправили.
Один из способов работы:
Response.Clear();
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Response.AddHeader(
"content-disposition", String.Format(CultureInfo.InvariantCulture, "attachment; filename={0}", fileName));
Response.BinaryWrite(package.GetAsByteArray());
Response.End();
Ответ 3
Как и Джо, мне все равно пришлось называть Response.ClearHeaders()
:
protected void btnDownload_Click(object sender, EventArgs e)
{
ExcelPackage pck = new ExcelPackage();
var ws = pck.Workbook.Worksheets.Add("Sample2");
ws.Cells["A1"].Value = "Sample 2";
ws.Cells["A1"].Style.Font.Bold = true;
var shape = ws.Drawings.AddShape("Shape1", eShapeStyle.Rect);
shape.SetPosition(50, 200);
shape.SetSize(200, 100);
shape.Text = "Sample 2 outputs the sheet using the Response.BinaryWrite method";
Response.Clear();
Response.ClearHeaders();
Response.BinaryWrite(pck.GetAsByteArray());
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Response.AddHeader("content-disposition", "attachment; filename=Sample2.xlsx");
Response.End();
}