打开使用EPPlus创建的.xlsx文件时出现问题,并使用ICSharpCode.SharpZipLib压缩到文件夹中
问题描述:
我正在使用EPPlus创建ExcelPackages(xlsx文档)列表,并将它们作为ZipEntries添加到ZipOutputStream中。我认为Excel文档应该是有效的,因为我可以在没有压缩的情况下将其中一个写入Response对象时打开它们。
按预期的方式建立压缩文件夹和文件(S),在那里,不似乎是空的,但是当我试图打开他们,我得到Excel中的以下错误:打开使用EPPlus创建的.xlsx文件时出现问题,并使用ICSharpCode.SharpZipLib压缩到文件夹中
Excel无法打开文件{Name} .xlsx,因为文件格式或文件扩展名无效。验证文件没有被损坏,该文件扩展名的文件
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();
至于列表中的文件的格式相匹配,我只是生成名称基于一些任意的东西,并加入了”的.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);
您先生,是一位天才。奇怪的是,我还没有看到任何示例中的代码,因为在发布之前,我一直在使用Google搜索这个问题。 –
@HansPetterNaumann不幸的是,我不是......我只是忘了多次寻找流... –
那么,我希望我下次会记住它。尽管如此,非常感谢! –