EPPlus保存到MemoryStream生成空文件,保存到本地文件功能正常
问题原因
- 核心诱因是
MemoryStream的指针位置问题:调用ExcelPackage.SaveAs(ms)写入完成后,流的Position属性会自动指向流的末尾,后续直接调用CopyTo等读取操作时,会从末尾开始读取,自然拿不到任何有效数据,导出的文件就会是空白状态。 - 不稳定复现的原因:不同项目中可能在写入后存在隐式重置
Position的操作,或者不同EPPlus版本的内部流处理逻辑存在差异,偶尔会自动把指针移到开头,才会出现时好时坏的表现。 - 额外可能原因:
ExcelPackage对象未执行Dispose操作时,部分缓冲区内容未完全刷入MemoryStream,也会导致内容缺失。
修复方案
你只需要对返回的MemoryStream做指针重置,同时规范ExcelPackage的资源释放逻辑即可,修正后的代码如下:
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.Position = 0; stream.CopyTo(new FileStream($@"Export\TestMs-{DateTime.Now.ToString("dd-MM-yy.H.mm.ss")}.xlsx", FileMode.Create)); stream.Dispose(); } 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() { using (ExcelPackage xl = new ExcelPackage()) { var ws = xl.Workbook.Worksheets.Add("TEST"); ws.Cells[1, 1].Value = "abc123"; MemoryStream ms = new MemoryStream(); xl.SaveAs(ms); // 这里也可以提前重置位置,避免外部调用遗漏 ms.Position = 0; return ms; } } }
注意事项
- 所有对流的读取操作(包括CopyTo、转字节数组、返回给前端下载等),都要确保操作前
Position为0 - 不要在
MemoryStream返回前执行Close或者Dispose操作,会导致外部无法读取流内容
内容的提问来源于stack exchange,提问作者Matthew Scerri
相关产品推荐
相关产品推荐

