【问题标题】:Create ZipArchive of Excel XLSX file with EPPLUS C#使用 EPPLUS C# 创建 Excel XLSX 文件的 ZipArchive
【发布时间】:2017-06-24 15:14:17
【问题描述】:

我有以下函数可以为我的 ASP.NET MVC 应用程序返回 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 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 文件。

我希望它返回一个压缩的单个文件。

这是当前结果的样子。

在使用@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;
                    }
                }
            }
        }

【问题讨论】:

  • 看起来应该是这样。 xlsx 文件是压缩的 opendocument 结构。我认为您的文件浏览器只是在目录层次结构中透明地显示 ZIP 内容(给定左上角的图标)。当您将 .zip 重命名为 .xlsx 时,您将能够使用 Excel 打开它。
  • + 你从来没有给newEntryStream写过任何东西?这个函数似乎只是返回带有 .zip 扩展名的 EPPlus 输出流(内部已经是 ZIP 并且应该具有 xlsx 扩展名)。
  • 看来你是对的。我去看看。

标签: c# excel zip archive epplus


【解决方案1】:

由于 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
                );
            }
        }
    }
}

测试和工作:

【讨论】:

  • 您好,我正在尝试获取 ZIP 文件而不是 EXCEL 填充文件。我已经知道如何获取 EXCEL 文件。 :)
  • @DragosDurlut - 对不起,我的错。用可行的解决方案更新了答案。
  • 他们是否使用修改后(更快)的压缩?或者第二次通过如何获得另外约 20% 的包装?
  • @kuujinbo 没问题。我将进行测试,并在这种情况下将其标记为答案。谢谢!向我 +1!
  • @DragosDurlut - 只是想回答您之前关于为什么 EPPlus 使用 DotNetZip 而不是 BCL 压缩/存档类的评论。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-05-09
  • 1970-01-01
  • 2016-03-08
  • 1970-01-01
  • 2018-09-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多