问题打开与EPPlus创建和压缩.xlsx文件的文件夹中有ICSharp code.SharpZipLib [英] Problems opening .xlsx file created with EPPlus and zipped in a folder with ICSharpCode.SharpZipLib

查看:726
本文介绍了问题打开与EPPlus创建和压缩.xlsx文件的文件夹中有ICSharp code.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();

至于文件名列表,我只是产生一个名字基于一些武断的东西,并加入了的.xl​​sx-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 use ToArray() 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆