2014-05-05 79 views
3

我正在使用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 「 - 擴展到它的結尾。

林不知道我哪裏會出錯,有什麼建議嗎?

回答

3

你必須倒帶內存流之前,你可以讀的東西(寫操作文件指針後,它的末日):

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); 
+2

您先生,是一位天才。奇怪的是,我還沒有看到任何示例中的代碼,因爲在發佈之前,我一直在使用Google搜索這個問題。 –

+1

@HansPetterNaumann不幸的是,我不是......我只是忘了多次尋找流... –

+0

那麼,我希望我下次會記住它。儘管如此,非常感謝! –

相關問題