Search code examples
epplusmemorystream

EPPlus - Saving to Memory Stream results in empty file, Saving to File works ok


I have what appears to be a strange problem with C# that I've not been able to figure out, hoping for some help here.

I've written the below demo that creates what is essentially the same file, but one Saves the ExcelPackage to a file using ExcelPackage.SaveAs(FileInfo(filePath)) (which works just fine and as expected), while the other saves to a MemoryStream (which results in a completely empty file).

Interestingly I do have other applications that utilise the same MemoryStream pattern and the file saves just fine, but it seems "temperamental" and can't figure out when it works and when it does not.

Anyone knows why this happens and how I can get it to work via a 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;
        }
    }

Solution

  • The problem is because you are not calling the Flush and Close methods for the FileStream. You should make use of the Using statement when using Streams as follows:

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