2017-02-07 138 views
2

我有以下函數爲我的ASP.NET MVC應用程序返回FileStreamResult使用EPPLUS創建Excel XLSX文件的ZipArchive C#

/// <summary> 
/// Generates a FileStreamResult containing a zip file with the EXCEL file in it 
/// </summary> 
/// <typeparam name="T">Type of object in the object list parameter</typeparam> 
/// <param name="objectList">The object list enumerable. This contains the data for the EXCEL file</param> 
/// <param name="fileName">The file name of the EXCEL</param> 
/// <returns>FileStreamResult</returns> 
public FileStreamResult CreateZipFileFileStreamResult<T>(IEnumerable<T> objectList, string fileName) 
{ 
    var ms = new MemoryStream(); 

    var contentType = System.Net.Mime.MediaTypeNames.Application.Zip; 

    ExcelPackage excelPackage = null; 

    ZipArchive archive = null; 

    try 
    { 
     excelPackage = new ExcelPackage(ms); 

     var workSheet1 = excelPackage.Workbook.Worksheets.Add("Sheet1"); 

     workSheet1.Cells["A1"].LoadFromCollection<T>(objectList, true); 

     excelPackage.SaveAs(ms); 



     ms.Seek(0, SeekOrigin.Begin); 

     archive = new ZipArchive(excelPackage.Stream, ZipArchiveMode.Create, true); 

     var newEntry = archive.CreateEntry(fileName, System.IO.Compression.CompressionLevel.Fastest); 

     var newEntryStream = newEntry.Open(); 

     var fsr = new FileStreamResult(excelPackage.Stream, contentType); 
     fsr.FileDownloadName = fileName + ".zip"; 

     return fsr; 
    } 
    catch (Exception ex) 
    { 
     if (archive != null) 
      archive.Dispose(); 

     if (excelPackage != null) 
      excelPackage.Dispose(); 

     if (ms != null) 
      ms.Dispose(); 

     throw; 
    } 
} 

該函數返回一些東西,但它是以拆分XML方式而不是一個XLSX文件。

我希望它能返回一個ZIPPED單個文件。

這是當前結果的樣子。

ZIP archive structure

已經使用我創造了這個功能@kuujinbo給予幫助。 請注意,出於某種原因FileContentResult工作和FileStreamResult不起作用。

 /// <summary> 
     /// Generates a FileStreamResult containing a zip file with the EXCEL file in it 
     /// </summary> 
     /// <typeparam name="T">Type of object in the object list parameter</typeparam> 
     /// <param name="objectList">The object list enumerable. This contains the data for the EXCEL file</param> 
     /// <param name="fileName">The file name of the EXCEL</param> 
     /// <returns>FileStreamResult</returns>   
     public FileContentResult CreateZipFileFileContentResult<T>(IEnumerable<T> objectList, string fileName) 
     { 
      var contentType = System.Net.Mime.MediaTypeNames.Application.Zip; 

      using (var memoryStream = new System.IO.MemoryStream()) 
      { 
       using (Ionic.Zip.ZipFile zip = new Ionic.Zip.ZipFile()) 
       { 
        using (var package = new OfficeOpenXml.ExcelPackage()) 
        { 
         var workSheet1 = package.Workbook.Worksheets.Add("Sheet1"); 
         workSheet1.Cells["A1"].LoadFromCollection<T>(objectList, true); 

         var firstRow = workSheet1.Row(1); 
         if (firstRow != null) 
          firstRow.Style.Font.Bold = true; 

         zip.AddEntry(fileName, package.GetAsByteArray()); 
         zip.Save(memoryStream); 
         var fcr = new FileContentResult(memoryStream.ToArray(), contentType); //NOTE: Using a File Stream Result will not work. 
         fcr.FileDownloadName = fileName + ".zip"; 
         return fcr; 
        } 
       } 
      } 
     } 
+0

樣子,這就是它應該是。 xlsx文件是壓縮的opendocument結構。我認爲你的文件瀏覽器只是在目錄層次結構中透明地顯示ZIP內容(給出左上角的圖標)。當您將.zip重命名爲.xlsx時,您將可以使用Excel打開它。 – dlatikay

+1

+你從不向'newEntryStream'寫任何東西?這個函數似乎只是返回帶有.zip擴展名的EPPlus輸出流(內部已經是ZIP,應該有xlsx擴展名)。 – dlatikay

+0

它說你是對的。我會看看。 –

回答

3

由於EPPlus 內部使用一個版本的DotNetZip,(看看源代碼)嘗試做相同的。恕我直言,他們的設計決定告訴了很多關於爲什麼一些選擇不是使用ZipArchive

class TestObject 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
} 

IEnumerable<TestObject> objectList = new List<TestObject>() 
{ 
    { new TestObject() {Id = 0, Name = "zero" } }, 
    { new TestObject() {Id = 1, Name = "one" } } 
}; 
string ExcelName = "test.xlsx"; 
string ZipName = "test.zip"; 

public ActionResult DotnetZip() 
{ 
    using (var stream = new MemoryStream()) 
    { 
     using (ZipFile zip = new ZipFile()) 
     { 
      using (var package = new ExcelPackage()) 
      { 
       var sheet = package.Workbook.Worksheets.Add("Sheet1"); 
       sheet.Cells["A1"].LoadFromCollection<TestObject>(objectList, true); 
       zip.AddEntry(ExcelName, package.GetAsByteArray()); 
       zip.Save(stream); 
       return File(
        stream.ToArray(), 
        System.Net.Mime.MediaTypeNames.Application.Zip, 
        ZipName 
       ); 
      } 
     } 
    } 
} 

測試和工作:

enter image description here

+0

你好,我試圖得到一個不是EXCEL文件的ZIP文件。我已經知道如何獲得EXCEL文件。 :) –

+1

@DragosDurlut - 對不起,我的壞。用一個可行的解決方案更新了答案。 – kuujinbo

+0

他們使用修改(更快)的壓縮?或者第二遍怎麼能再獲得20%的包裝呢? – dlatikay

相關問題