打开使用EPPlus创建的.xlsx文件并使用ICSharpCode.SharpZipLib压缩到一个文件夹时出现问题

我正在使用EPPlus创建ExcelPackages(xlsx文档)列表,并将它们作为ZipEntries添加到ZipOutputStream中。 我认为Excel文档应该是有效的,因为当我将其中一个文件写入Response对象而不进行压缩时,我可以正常打开它们。
zip文件夹是按预期创建的,文件在那里并且似乎没有空,但是当我尝试打开它们时,我在Excel中收到以下错误:

Excel无法打开文件{Name} .xlsx,因为文件格式或文件扩展名无效。 validation文件是否已损坏,以及文件扩展名是否与文件格式匹配

List documents = new List(); List fileNames = new List(); //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(); 

至于文件名列表,我只是根据一些任意的东西生成一个名称,并在其末尾添加“.xlsx”扩展名。

我不知道我在哪里出错,有什么建议吗?

您必须先回滚内存流,然后才能读取内容(在写操作文件指针结束后):

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

这就是说MemoryStream只不过是一个字节数组,所以你甚至不需要分配和读取一个新的代码:

 buffer = new byte[ms.Length]; ms.Read(buffer, 0, buffer.Length); entry.Size = ms.Length; ms.Close(); zipOutputStream.Write(buffer, 0, buffer.Length); 

可以简单地替换为:

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

最后注意事项:如果您不想使用内部MemoryStream缓冲区(出于任何原因)并且您想要它的修剪副本(当您手动操作时),那么只需使用ToArray()方法,如下所示:

 var buffer = ms.ToArray(); ms.Close(); entry.Size = buffer.Length; zipOutputStream.Write(buffer, 0, buffer.Length);