问题打开与EPPlus创建和压缩.xlsx文件的文件夹中有ICSharp code.SharpZipLib [英] Problems opening .xlsx file created with EPPlus and zipped in a folder with ICSharpCode.SharpZipLib
问题描述
我创建使用EPPlus ExcelPackages(XLSX文件)的列表,并将其添加到一个ZipOutputStream为ZipEntries。我认为Excel文档应该是有效的,因为我可以打开他们就好了,当我写的其中一人Response对象不荏苒。结果
按预期的方式创建的zip文件夹和文件(S)在那里,不似乎是空的,但是当我试图打开他们,我得到在Excel中出现以下错误:
Excel无法打开文件{}名称,因为原来的.xlsx文件格式或文件扩展名无效。验证文件还没有被破坏,该文件的扩展名的文件的格式相匹配
块引用>列表< ExcelPackage>文件=新的List< ExcelPackage>();
清单<串GT;文件名=新的List<串GT;();(删除了可读性的缘故)// code在这里获取的文件和文件名Response.Clear();
Context.Response.BufferOutput = FALSE;
Response.ContentType =应用程序/压缩
Response.AppendHeader(内容处置,附件;文件名= \\random-foldername.zip \\);
Response.CacheControl =私人;
Response.Cache.SetExpires(DateTime.Now.AddMinutes(3));ZipOutputStream zipOutputStream =新ZipOutputStream(Response.OutputStream);
zipOutputStream.SetLevel(3); // 0-9,9是COM pression的最高水平
字节[]缓冲= NULL;的for(int i = 0; I< documents.Count;我++)
{
MemoryStream的毫秒=新的MemoryStream(); 文件[I] .SaveAs(毫秒); 入门的ZipEntry =新的ZipEntry(ZipEntry.CleanName(文件名由[i])); zipOutputStream.PutNextEntry(输入);
缓冲区=新的字节[ms.Length] ms.Read(缓冲液,0,buffer.Length);
entry.Size = ms.Length; ms.Close(); zipOutputStream.Write(缓冲液,0,buffer.Length);
zipOutputStream.CloseEntry();}
zipOutputStream.Finish();
zipOutputStream.Close();到Response.End();至于文件名列表,我只是产生一个名字基于一些武断的东西,并加入了的.xlsx-extension到它的结束。
林不知道在哪里我去错在这里,有什么建议?
解决方案您必须后退内存流之前,你可以读的东西(写操作的文件指针后,它的结束):
ms.Seek(0,SeekOrigin.Begin)
ms.Read(缓冲液,0,buffer.Length);这表示,
的MemoryStream
无非是一个字节数组,所以你甚至都不需要来分配和读取一个新的那么这code:缓冲液=新的字节[ms.Length]ms.Read(缓冲液,0,buffer.Length);
entry.Size = ms.Length;ms.Close();zipOutputStream.Write(缓冲液,0,buffer.Length);能以简单的替换:
entry.Size = ms.Length;
zipOutputStream.Write(ms.GetBuffer(),0,ms.Length);
ms.Close();最后一点:如果你不想使用内部
的MemoryStream
缓冲区(出于任何原因),你想它的一个副本修剪(如你正在做手工),那么只需使用ToArray的()
的方法是这样的:VAR缓冲= ms.ToArray();
ms.Close();
entry.Size = buffer.Length;
zipOutputStream.Write(缓冲液,0,buffer.Length);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?
解决方案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 useToArray()
method like this:var buffer = ms.ToArray(); ms.Close(); entry.Size = buffer.Length; zipOutputStream.Write(buffer, 0, buffer.Length);
这篇关于问题打开与EPPlus创建和压缩.xlsx文件的文件夹中有ICSharp code.SharpZipLib的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!