2017-02-07 135 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

相关问题