【问题标题】:EPPlus - Saving to Memory Stream results in empty file, Saving to File works okEPPlus - 保存到内存流会导致空文件,保存到文件工作正常
【发布时间】:2021-10-30 11:40:03
【问题描述】:

我有一个似乎是 C# 的奇怪问题,我无法弄清楚,希望在这里得到一些帮助。

我编写了下面的演示,它创建了本质上相同的文件,但是一个使用ExcelPackage.SaveAs(FileInfo(filePath))ExcelPackage 保存到一个文件中(它工作得很好,正如预期的那样),而另一个保存到一个@ 987654323@(这会导致文件完全为空)。

有趣的是,我确实有其他应用程序使用相同的MemoryStream 模式并且文件保存得很好,但它似乎“脾气暴躁”,无法弄清楚它何时有效,何时无效。

任何人都知道为什么会发生这种情况以及我如何通过MemoryStream 让它工作?

    class Program
    {
        static void Main(string[] args)
        {
            ExcelPackage.LicenseContext = LicenseContext.NonCommercial;

            TestXLToFile($@"Export\Test-{DateTime.Now.ToString("dd-MM-yy.H.mm.ss")}.xlsx");

            var stream = TestXLToMemStream();

            stream.CopyTo(new FileStream($@"Export\TestMs-{DateTime.Now.ToString("dd-MM-yy.H.mm.ss")}.xlsx", FileMode.Create));
        }

        public static void TestXLToFile(string FilePath)
        {
            using (ExcelPackage xl = new ExcelPackage())
            {
                var ws = xl.Workbook.Worksheets.Add("TEST");
                ws.Cells[1, 1].Value = "abc123";

                xl.SaveAs(new FileInfo(FilePath));
            }
        }

        public static MemoryStream TestXLToMemStream()
        {
            ExcelPackage xl = new ExcelPackage();

            var ws = xl.Workbook.Worksheets.Add("TEST");
            ws.Cells[1, 1].Value = "abc123";

            MemoryStream ms = new MemoryStream();
            xl.SaveAs(ms);

            return ms;
        }
    }

【问题讨论】:

  • 这两个函数有几个不同之处。一个在ExcelPackage(通过using-block)上调用Dispose,一个没有。一个通过FileInfo,另一个通过Stream。如果您使用 FileStream 而不是 FileInfo 会发生什么?
  • 如果您使用 GetAsByteArray() 而不是 SaveAs(MemoryStream) 会怎样? (当然你可以从字节数组中创建一个MemoryStream,然后)
  • 另外,您使用MemoryStream 的代码会泄漏它复制到的FileStream永远不会刷新。这是一个很大的禁忌。只需将stream.CopyTo(new FileStream(...)) 更改为using (var fs = new FileStream(...)) stream.CopyTo(fs); 即可解决您的问题。
  • 感谢@BenVoigt 感谢您的帮助。传递 FileStream 有效,但这意味着 SaveAs 保存到磁盘,我想避免这种情况(我需要将 MemoryStream 传递给服务)。我也刷新了MemoryStream,但仍然得到一个 0kb 的文件。不过,感谢您的提醒。使用GetAsByteArray() 会导致数据被写入,但文件已损坏。在某些情况下,相同的代码字(如果我在工作表中添加更多数据),这让我怀疑这是EPPlus 问题?让我看看能不能演示一下。
  • 抱歉,刚刚看到编辑using (var fs = new FileStream($@"<file_path>", FileMode.Create)) stream.CopyTo(fs); 仍然导致文件为空

标签: epplus memorystream


【解决方案1】:

问题是因为您没有为 FileStream 调用 Flush 和 Close 方法。使用 Streams 时应使用 Using 语句,如下所示:

using(var stream = TestXLToMemStream())
using(var fileStream = new FileStream($@"Export\TestMS-{DateTime.Now.ToString("dd-MM-yy.H.mm.ss")}.xlsx", FileMode.Create, FileAccess.Write))
{
    stream.WriteTo(fileStream);
}

【讨论】:

猜你喜欢
  • 2012-02-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-29
  • 1970-01-01
相关资源
最近更新 更多