【发布时间】: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