diff --git a/ExcelMapper/ExcelMapper.cs b/ExcelMapper/ExcelMapper.cs index b9c45d1..b283787 100644 --- a/ExcelMapper/ExcelMapper.cs +++ b/ExcelMapper/ExcelMapper.cs @@ -1082,11 +1082,32 @@ public async Task SaveAsync(Stream stream, IEnumerable objects, string she /// Index of the sheet. /// if set to true saves in .xlsx format; otherwise, saves in .xls format. /// converter receiving property name and value - public async Task SaveAsync(Stream stream, IEnumerable objects, int sheetIndex = 0, bool xlsx = true, Func valueConverter = null) - { - using var ms = new MemoryStream(); + public async Task SaveAsync(Stream stream, IEnumerable objects, int sheetIndex = 0, bool xlsx = true, Func valueConverter = null) { + using var ms = new NpoiMemoryStream() { AllowClose = false }; Save(ms, objects, sheetIndex, xlsx, valueConverter); - await SaveAsync(stream, ms); + await SaveAsync(stream, ms); + } + + /// + /// The above code fails because the Workbook.Save closes the stream + /// before it can copy the data between the streams. + /// + public class NpoiMemoryStream : MemoryStream { + public NpoiMemoryStream() { + // We always want to close streams by default to + // force the developer to make the conscious decision + // to disable it. Then, they're more apt to remember + // to re-enable it. The last thing you want is to + // enable memory leaks by default. ;-) + AllowClose = true; + } + + public bool AllowClose { get; set; } + + public override void Close() { + if (AllowClose) + base.Close(); + } } ///