When I try to generate an Excel file using EPPlus, Excel give me the following error message:
Excel cannot open the file 'myfilename.xlsx' because the file format or file extension is not valid. Verify the the file has not been corrupted and that the file extension matches the format of the file.
Here's my code:
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);
}
}
Any idea what I'm doing wrong?
NET Core from version 2.0. EPPlus has no dependencies to any other library such as Microsoft Excel. The library is designed with the developer in mind.
EPPlus 5/6 has new methods added to the ExcelRange for exporting data to csv files, streams, strings and data tables.
EPPlus does not work with the XLS format. Only XLSX. You'll need to find a new library.
EPPlus is a very helpful open-source 3rd party DLL for writing data to excel. EPPlus supports multiple properties of spreadsheets like cell ranges, cell styling, charts, pictures, shapes, comments, tables, protection, encryption, pivot tables, data validation, conditional formatting, formula calculation, etc.
All you need to do is reset the stream position. stream.Position = 0;
You shouldn't write directly to the Response, it's not the MVC way. It doesn't follow the correct MVC pipeline and it tightly couples your controller action code to the Response object.
When you add a file name as the 3rd parameter in File()
, MVC automatically adds the correct Content-Disposition
header... so you shouldn't need to add it manually.
The short of it is, this is what you want:
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);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With