Problems opening .xlsx file created with EPPlus and zipped in a folder with ICSharpCode.SharpZipLib

StackOverflow https://stackoverflow.com/questions/23472385

Domanda

I am creating a list of ExcelPackages (xlsx documents) using EPPlus, and adding them to a ZipOutputStream as ZipEntries. I think the Excel documents should be valid, as I can open them just fine when I write one of them to the Response object without zipping.
The zip folder is created as expected, and the file(s) are there and doesnt seem to be empty, but when I try to open them I get the following error in Excel:

Excel cannot open the file {Name}.xlsx because the file format or file extension is not valid. Verify that file has not been corrupted and that the file extension matches the format of the file

List<ExcelPackage> documents = new List<ExcelPackage>();
List<string> fileNames = new List<string>();

//Code for fetching documents and filenames here (removed for the sake of readability)

Response.Clear();
Context.Response.BufferOutput = false; 
Response.ContentType = "application/zip";
Response.AppendHeader("content-disposition", "attachment; filename=\"random-foldername.zip\"");
Response.CacheControl = "Private";
Response.Cache.SetExpires(DateTime.Now.AddMinutes(3)); 

ZipOutputStream zipOutputStream = new ZipOutputStream(Response.OutputStream);
zipOutputStream.SetLevel(3); //0-9, 9 being the highest level of compression
byte[] buffer = null;

for (int i = 0; i < documents.Count; i++)
{
    MemoryStream ms = new MemoryStream();

    documents[i].SaveAs(ms);

    ZipEntry entry = new ZipEntry(ZipEntry.CleanName(fileNames[i]));

    zipOutputStream.PutNextEntry(entry);
    buffer = new byte[ms.Length];

    ms.Read(buffer, 0, buffer.Length);
    entry.Size = ms.Length;

    ms.Close();

    zipOutputStream.Write(buffer, 0, buffer.Length);
    zipOutputStream.CloseEntry();

}
zipOutputStream.Finish();
zipOutputStream.Close();

Response.End();

As for the list of filenames, im just generating a name based on some arbitrary stuff and adding a ".xlsx"-extension to the end of it.

Im not sure where im going wrong here, any suggestions?

È stato utile?

Soluzione

You have to rewind memory stream before you can read something (after write operation file pointer is that its end):

ms.Seek(0, SeekOrigin.Begin)
ms.Read(buffer, 0, buffer.Length);

That said a MemoryStream is nothing more than a byte array so you don't even need to allocate and read a new one then this code:

buffer = new byte[ms.Length];

ms.Read(buffer, 0, buffer.Length);
entry.Size = ms.Length;

ms.Close();

zipOutputStream.Write(buffer, 0, buffer.Length);

Can be simply replaced with:

entry.Size = ms.Length;
zipOutputStream.Write(ms.GetBuffer(), 0, ms.Length);
ms.Close();

Final note: if you don't want to use internal MemoryStream buffer (for any reason) and you want a trimmed copy of it (as you're doing manually) then simply use ToArray() method like this:

var buffer = ms.ToArray();
ms.Close();
entry.Size = buffer.Length;
zipOutputStream.Write(buffer, 0, buffer.Length);
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top