2012-03-07 6 views
13

При попытке сгенерировать файл Excel с помощью EPPlus, Excel дает мне следующее сообщение об ошибке:Генерация файла Excel с EPPlus не удается

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); 
    } 
} 

Любая идея, что я делаю неправильно?

+0

говорит ошибка 'myfilename.xslx' в то время как ваш код показывает 'myfilename.xlsx'. Какой из них вы действительно используете? –

+0

Ответил [вчера] (http://stackoverflow.com/a/9574414/284240). Я предполагаю, что это та же проблема. –

+0

@ M.Babcock - xlsx, это была опечатка. Я отредактирую вопрос. –

ответ

27

Все, что вам нужно сделать, это сбросить позицию потока. stream.Position = 0;

не следует писать непосредственно на ответ, это не способ MVC. Он не соответствует правильному конвейеру MVC и плотно соединяет ваш код действия контроллера с объектом Response.

Когда вы добавляете имя файла в качестве третьего параметра в 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); 
    } 
} 
+0

Итак, вопрос об этом, я использую аналогичный метод, хотя в настоящее время я возвращаю FileStreamResponse вместо файлового объекта.Проблема, с которой я сталкиваюсь, заключается в том, что если пользователь делает несколько запросов во время создания первого файла, все они, похоже, блокируются и метод saveas никогда не завершается. Вы столкнулись с этим с EPPlus? – Shawn

10

Ваш код не отображает 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(); 
+0

Метод 'File' является частью' ASP.Net MVC'. Я попробую! –

+0

Странно, теперь он говорит: «Excel нашел нечитаемый контент в« myfilename.xlsx ». Вы хотите восстановить содержимое этой книги? Если вы доверяете источнику этой книги, нажмите« Да ». Если я нажму «Да», это сработает, но я понятия не имею, что это такое. –

+0

Я видел это сообщение об ошибке раньше, IIRC это произошло, когда Response.Clear() был опущен. Другая возможность заключается в том, что ошибка EPPlus приводит к недействительным данным в файле. Вы можете проверить, что это, сохраняя файл на сервере и видя, есть ли у вас такая же ошибка при открытии на сервере. – Joe

2

Подобный ответ Джо, я все еще должен был назвать 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(); 
    }