11 Commits 8b758fab38 ... e4eef0635d

Author SHA1 Message Date
  Piotr Czajkowski e4eef0635d Notes 2 months ago
  Piotr Czajkowski 840d4d3778 Added Dispose to ExcelDynamicWriter, #5 2 months ago
  Piotr Czajkowski 65a8eed2a7 Added Dispose to ExcelDynamicReader 2 months ago
  Piotr Czajkowski ddfa0913ae Added Dispose to ExcelReader 2 months ago
  Piotr Czajkowski c98fe62b7d Added Dispose to ExcelWriter 2 months ago
  Piotr Czajkowski 7af8d1dcf6 Added WriteReadInMemory for dynamic 2 months ago
  Piotr Czajkowski 357260d4a2 Added WriteReadInMemory 2 months ago
  Piotr Czajkowski b48482c223 Got rid of warnings 2 months ago
  Piotr Czajkowski 5628b40fdc More constructors 2 months ago
  Piotr Czajkowski c888c95a44 Added constructor for ExcelReader 2 months ago
  Piotr Czajkowski c2dc285e33 Added constructor 2 months ago

+ 21 - 1
ExcelORM/ExcelORM/ExcelDynamicReader.cs

@@ -3,7 +3,7 @@ using ExcelORM.Models;
 
 namespace ExcelORM;
 
-public class ExcelDynamicReader
+public class ExcelDynamicReader : IDisposable
 {
     private readonly IXLWorkbook xlWorkbook;
     public bool SkipHidden { get; set; }
@@ -14,6 +14,11 @@ public class ExcelDynamicReader
         xlWorkbook = new XLWorkbook(path);
     }
 
+    public ExcelDynamicReader(IXLWorkbook workbook)
+    {
+        xlWorkbook = workbook ?? throw new ArgumentNullException(nameof(workbook));
+    }
+
     private IEnumerable<List<DynamicCell>> ProcessRows(IEnumerable<IXLRow> rows, List<DynamicCell> mapping)
     {
         foreach (var row in rows)
@@ -103,4 +108,19 @@ public class ExcelDynamicReader
             };
         }
     }
+
+    public void Dispose()
+    {
+        Dispose(true);
+        GC.SuppressFinalize(this);
+    }
+
+    protected virtual void Dispose(bool disposing)
+    {
+        if (disposing)
+        {
+            xlWorkbook?.Dispose();
+        }
+    }
+    ~ExcelDynamicReader() => Dispose(false);
 }

+ 26 - 4
ExcelORM/ExcelORM/ExcelDynamicWriter.cs

@@ -4,7 +4,7 @@ using ExcelORM.Models;
 
 namespace ExcelORM;
 
-public class ExcelDynamicWriter
+public class ExcelDynamicWriter : IDisposable
 {
     private readonly IXLWorkbook xlWorkbook;
     public ExcelDynamicWriter(string? path = null)
@@ -12,6 +12,11 @@ public class ExcelDynamicWriter
         xlWorkbook = File.Exists(path) ? new XLWorkbook(path) : new XLWorkbook();
     }
 
+    public ExcelDynamicWriter(IXLWorkbook workbook)
+    {
+        xlWorkbook = workbook ?? throw new ArgumentNullException(nameof(workbook));
+    }
+
     private static int GenerateHeader(IXLWorksheet worksheet, IEnumerable<DynamicCell> firstRow)
     {
         var rowIndex = 1;
@@ -25,17 +30,19 @@ public class ExcelDynamicWriter
     {
         var rowIndex = append switch
         {
-            true => worksheet.LastRowUsed().RowNumber() + 1,
+            true => worksheet.LastRowUsed()?.RowNumber() + 1,
             false => GenerateHeader(worksheet, values.First()),
         };
 
+        if (rowIndex == null) throw new NullReferenceException(nameof(rowIndex));
+
         foreach (var row in values)
         {
             foreach (var cell in row)
             {
                 if (cell.Value == null) continue;
 
-                worksheet.Cell(rowIndex, cell.Position).Value = XLCellValue.FromObject(cell.Value);
+                worksheet.Cell(rowIndex.Value, cell.Position).Value = XLCellValue.FromObject(cell.Value);
             }
 
             rowIndex++;
@@ -67,5 +74,20 @@ public class ExcelDynamicWriter
     {
         xlWorkbook.SaveAs(path);
         converter?.MakeCompatible(path);
-    } 
+    }
+
+    public void Dispose()
+    {
+        Dispose(true);
+        GC.SuppressFinalize(this);
+    }
+
+    protected virtual void Dispose(bool disposing)
+    {
+        if (disposing)
+        {
+            xlWorkbook?.Dispose();
+        }
+    }
+    ~ExcelDynamicWriter() => Dispose(false);
 }

+ 4 - 4
ExcelORM/ExcelORM/ExcelORM.csproj

@@ -1,10 +1,10 @@
-<Project Sdk="Microsoft.NET.Sdk">
+<Project Sdk="Microsoft.NET.Sdk">
 
     <PropertyGroup>
         <TargetFramework>net8.0</TargetFramework>
         <ImplicitUsings>enable</ImplicitUsings>
         <Nullable>enable</Nullable>
-        <Version>2.3.1</Version>
+        <Version>2.4.0</Version>
         <PackageProjectUrl>https://git.liox.eu/pczajkowski/ExcelORM</PackageProjectUrl>
         <RepositoryUrl>https://github.com/pczajkowski/ExcelORM</RepositoryUrl>
         <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
@@ -14,11 +14,11 @@
 	<Authors>Piotr Czajkowski</Authors>
 	<Description>Simple library to read/write C# objects from/to Excel files. </Description>
 	<RepositoryType>GitHub</RepositoryType>
-	<PackageReleaseNotes>Write now has headerRowIndex for append.</PackageReleaseNotes>
+	<PackageReleaseNotes>Constructors now accept IXLWorkbook. Implemented IDisposable.</PackageReleaseNotes>
     </PropertyGroup>
 
     <ItemGroup>
-	    <PackageReference Include="ClosedXML" Version="0.102.3" />
+	    <PackageReference Include="ClosedXML" Version="0.104.1" />
 	    <None Include="../../README.md" Pack="true" PackagePath="\" />
 	    <None Include="../../LICENSE" Pack="true" PackagePath="" />
     </ItemGroup>

+ 21 - 2
ExcelORM/ExcelORM/ExcelReader.cs

@@ -1,16 +1,20 @@
 using System.Runtime.CompilerServices;
 using ClosedXML.Excel;
-using ExcelORM.Interfaces;
 using ExcelORM.Models;
 
 namespace ExcelORM;
 
-public class ExcelReader
+public class ExcelReader : IDisposable
 {
     private readonly IXLWorkbook xlWorkbook;
     public bool SkipHidden { get; set; }
     public bool ObeyFilter { get; set; }
 
+    public ExcelReader(IXLWorkbook workbook)
+    {
+        xlWorkbook = workbook ?? throw new ArgumentNullException(nameof(workbook));
+    }
+
     public ExcelReader(string? path)
     {
         xlWorkbook = new XLWorkbook(path);
@@ -105,4 +109,19 @@ public class ExcelReader
                 yield return item;
         }
     }
+
+    public void Dispose()
+    {
+        Dispose(true);
+        GC.SuppressFinalize(this);
+    }
+
+    protected virtual void Dispose(bool disposing)
+    {
+        if (disposing)
+        {
+            xlWorkbook?.Dispose();
+        }
+    }
+    ~ExcelReader() => Dispose(false);
 }

+ 28 - 6
ExcelORM/ExcelORM/ExcelWriter.cs

@@ -6,7 +6,7 @@ using ExcelORM.Models;
 
 namespace ExcelORM;
 
-public class ExcelWriter
+public class ExcelWriter : IDisposable
 {
     private readonly IXLWorkbook xlWorkbook;
     public ExcelWriter(string? path = null)
@@ -14,6 +14,11 @@ public class ExcelWriter
         xlWorkbook = File.Exists(path) ? new XLWorkbook(path) : new XLWorkbook();
     }
 
+    public ExcelWriter(IXLWorkbook workbook)
+    {
+        xlWorkbook = workbook ?? throw new ArgumentNullException(nameof(workbook));
+    }
+
     private static int GenerateHeader<T>(IXLWorksheet worksheet, PropertyInfo[] properties) where T : class
     {
         var rowIndex = 1;
@@ -74,23 +79,25 @@ public class ExcelWriter
     {
         if (!values.Any()) return;
 
-        int rowIndex;
+        int? rowIndex;
         var properties = typeof(T).GetProperties();
         List<Mapping>? mapping = [];
 
         if (append)
         {
-            rowIndex = worksheet.LastRowUsed().RowNumber() + 1;
-            var headerCells = headerRowIndex != null ? worksheet.Row((int)headerRowIndex).CellsUsed() : worksheet.FirstRowUsed().CellsUsed();
+            rowIndex = worksheet.LastRowUsed()?.RowNumber() + 1;
+            var headerCells = headerRowIndex != null ? worksheet.Row((int)headerRowIndex).CellsUsed() : worksheet.FirstRowUsed()?.CellsUsed();
             mapping = Mapping.MapProperties<T>(headerCells);
             if (mapping == null || mapping.Count == 0) return;
         } else
             rowIndex = GenerateHeader<T>(worksheet, properties);
 
+        if (rowIndex == null) throw new NullReferenceException(nameof(rowIndex));
+
         foreach (var value in values)
         {
-            if (append) WriteRowAppend(value, worksheet, properties, rowIndex, mapping);
-            else WriteRow(value, worksheet, properties, rowIndex);
+            if (append) WriteRowAppend(value, worksheet, properties, rowIndex.Value, mapping);
+            else WriteRow(value, worksheet, properties, rowIndex.Value);
             
             rowIndex++;
         }
@@ -112,4 +119,19 @@ public class ExcelWriter
         xlWorkbook.SaveAs(path);
         converter?.MakeCompatible(path);
     } 
+
+    public void Dispose()
+    {
+        Dispose(true);
+        GC.SuppressFinalize(this);
+    }
+
+    protected virtual void Dispose(bool disposing)
+    {
+        if (disposing)
+        {
+            xlWorkbook?.Dispose();
+        }
+    }
+    ~ExcelWriter() => Dispose(false);
 }

+ 4 - 4
ExcelORM/ExcelORMTests/DynamicReaderTests.cs

@@ -12,7 +12,7 @@ public class DynamicReaderTests
     [Fact]
     public void Read()
     {
-        var reader = new ExcelDynamicReader(RegularFile);
+        using var reader = new ExcelDynamicReader(RegularFile);
         var results = reader.Read("Sheet 1").ToArray();
         Assert.NotEmpty(results);
     }
@@ -20,7 +20,7 @@ public class DynamicReaderTests
     [Fact]
     public void ReadDifferentTypes()
     {
-        var reader = new ExcelDynamicReader(DifferentTypesFile);
+        using var reader = new ExcelDynamicReader(DifferentTypesFile);
         var results = reader.Read().ToArray();
         Assert.NotEmpty(results);
 
@@ -35,7 +35,7 @@ public class DynamicReaderTests
     [Fact]
     public void ReadAll()
     {
-        var reader = new ExcelDynamicReader(MultipleSheetsFile);
+        using var reader = new ExcelDynamicReader(MultipleSheetsFile);
         var results = reader.ReadAll().ToArray();
         Assert.NotEmpty(results);
     }
@@ -43,7 +43,7 @@ public class DynamicReaderTests
     [Fact]
     public void ReadDifficult()
     {
-        var reader = new ExcelDynamicReader(DifficultFile);
+        using var reader = new ExcelDynamicReader(DifficultFile);
         var results = reader.Read().ToArray();
         Assert.NotEmpty(results);
         Assert.Equal(results.First().Count, results.Last().Count);

+ 26 - 6
ExcelORM/ExcelORMTests/DynamicWriterTests.cs

@@ -1,3 +1,4 @@
+using ClosedXML.Excel;
 using ExcelORM;
 
 namespace ExcelORMTests;
@@ -13,15 +14,15 @@ public class DynamicWriterTests
         var testFile = Path.GetRandomFileName();
         testFile = Path.ChangeExtension(testFile, "xlsx");
 
-        var reader = new ExcelDynamicReader(DifficultFile);
+        using var reader = new ExcelDynamicReader(DifficultFile);
         var results = reader.Read().ToArray();
         Assert.NotEmpty(results);
 
-        var writer = new ExcelDynamicWriter();
+        using var writer = new ExcelDynamicWriter();
         writer.Write(results);
         writer.SaveAs(testFile);
 
-        var savedReader = new ExcelDynamicReader(testFile);
+        using var savedReader = new ExcelDynamicReader(testFile);
         var savedResults = savedReader.Read().ToArray();
         Assert.NotEmpty(savedResults);
         Assert.True(results.First().SequenceEqual(savedResults.First()));
@@ -36,15 +37,15 @@ public class DynamicWriterTests
         var testFile = Path.GetRandomFileName();
         testFile = Path.ChangeExtension(testFile, "xlsx");
 
-        var reader = new ExcelDynamicReader(MultipleSheetsFile);
+        using var reader = new ExcelDynamicReader(MultipleSheetsFile);
         var results = reader.ReadAll().ToArray();
         Assert.NotEmpty(results);
         
-        var writer = new ExcelDynamicWriter();
+        using var writer = new ExcelDynamicWriter();
         writer.WriteAll(results);
         writer.SaveAs(testFile);
 
-        var savedReader = new ExcelDynamicReader(testFile);
+        using var savedReader = new ExcelDynamicReader(testFile);
         var savedResults = savedReader.ReadAll().ToArray();
         Assert.NotEmpty(savedResults);
         Assert.Equal(results.First().Name, savedResults.First().Name);
@@ -54,4 +55,23 @@ public class DynamicWriterTests
 
         File.Delete(testFile);
     }
+
+    [Fact]
+    public void WriteReadInMemory()
+    {
+        using var readWorkbook = new XLWorkbook(DifficultFile);
+        using var reader = new ExcelDynamicReader(readWorkbook);
+        var results = reader.Read().ToArray();
+        Assert.NotEmpty(results);
+
+        using var writeWorkbook = new XLWorkbook();
+        using var writer = new ExcelDynamicWriter(writeWorkbook);
+        writer.Write(results);
+
+        using var savedReader = new ExcelDynamicReader(writeWorkbook);
+        var savedResults = savedReader.Read().ToArray();
+        Assert.NotEmpty(savedResults);
+        Assert.True(results.First().SequenceEqual(savedResults.First()));
+        Assert.True(results.Last().SequenceEqual(savedResults.Last()));
+    }
 }

+ 2 - 2
ExcelORM/ExcelORMTests/ExcelORMTests.csproj

@@ -10,8 +10,8 @@
     </PropertyGroup>
 
     <ItemGroup>
-        <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.10.0" />
-        <PackageReference Include="xunit" Version="2.9.0" />
+        <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.1" />
+        <PackageReference Include="xunit" Version="2.9.2" />
         <PackageReference Include="xunit.runner.visualstudio" Version="2.8.2">
             <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
             <PrivateAssets>all</PrivateAssets>

+ 11 - 11
ExcelORM/ExcelORMTests/ReaderTests.cs

@@ -15,7 +15,7 @@ public class ReaderTests
     [Fact]
     public void Read()
     {
-        var reader = new ExcelReader(RegularFile);
+        using var reader = new ExcelReader(RegularFile);
         var results = reader.Read<Test>().ToArray();
         Assert.NotEmpty(results);
     }
@@ -23,11 +23,11 @@ public class ReaderTests
     [Fact]
     public void ReadHidden()
     {
-        var reader = new ExcelReader(HiddenFile);
+        using var reader = new ExcelReader(HiddenFile);
         var results = reader.Read<Test>().ToArray();
         Assert.NotEmpty(results);
 
-        var readerHidden = new ExcelReader(HiddenFile) { SkipHidden = true };
+        using var readerHidden = new ExcelReader(HiddenFile) { SkipHidden = true };
         var resultsHidden = readerHidden.Read<Test>().ToArray();
         Assert.NotEmpty(resultsHidden);
         Assert.NotEqual(results.Length, resultsHidden.Length);
@@ -36,11 +36,11 @@ public class ReaderTests
     [Fact]
     public void ReadFiltered()
     {
-        var reader = new ExcelReader(FilteredFile);
+        using var reader = new ExcelReader(FilteredFile);
         var results = reader.Read<Test>().ToArray();
         Assert.NotEmpty(results);
 
-        var readerFiltered = new ExcelReader(FilteredFile) { ObeyFilter = true };
+        using var readerFiltered = new ExcelReader(FilteredFile) { ObeyFilter = true };
         var resultsFiltered = readerFiltered.Read<Test>().ToArray();
         Assert.NotEmpty(resultsFiltered);
         Assert.NotEqual(results.Length, resultsFiltered.Length);
@@ -49,7 +49,7 @@ public class ReaderTests
     [Fact]
     public void ReadDifficult()
     {
-        var reader = new ExcelReader(DifficultFile);
+        using var reader = new ExcelReader(DifficultFile);
         var results = reader.Read<Test>("Tab").ToArray();
         Assert.NotEmpty(results);
 
@@ -66,7 +66,7 @@ public class ReaderTests
     [Fact]
     public void ReadMultipleSheets()
     {
-        var reader = new ExcelReader(MultipleSheetsFile);
+        using var reader = new ExcelReader(MultipleSheetsFile);
         var results = reader.ReadAll<Test>().ToArray();
         Assert.NotEmpty(results);
         Assert.Equal(6, results.Length);
@@ -75,7 +75,7 @@ public class ReaderTests
     [Fact]
     public void ReadDifferentTypes()
     {
-        var reader = new ExcelReader(DifferentTypesFile);
+        using var reader = new ExcelReader(DifferentTypesFile);
         var results = reader.Read<TestTypes>().ToArray();
         Assert.NotEmpty(results);
     }
@@ -83,7 +83,7 @@ public class ReaderTests
     [Fact]
     public void ReadDifferentTypesWithSkip()
     {
-        var reader = new ExcelReader(DifferentTypesFile);
+        using var reader = new ExcelReader(DifferentTypesFile);
         var results = reader.Read<TestSkip>().ToArray();
         Assert.NotEmpty(results);
         Assert.All(results, x => Assert.Null(x.Text));
@@ -94,7 +94,7 @@ public class ReaderTests
     [Fact]
     public void ReadDifferentTypesWithSkipMiddle()
     {
-        var reader = new ExcelReader(DifferentTypesFile);
+        using var reader = new ExcelReader(DifferentTypesFile);
         var results = reader.Read<TestSkipMiddle>().ToArray();
         Assert.NotEmpty(results);
         Assert.NotNull(results.FirstOrDefault(x => x.Text != null));
@@ -105,7 +105,7 @@ public class ReaderTests
     [Fact]
     public void ReadWithFormula()
     {
-        var reader = new ExcelReader(WithFormulaFile);
+        using var reader = new ExcelReader(WithFormulaFile);
         var results = reader.Read<TestWithFormula>().ToArray();
         Assert.NotEmpty(results);
     }

+ 40 - 24
ExcelORM/ExcelORMTests/WriterTests.cs

@@ -26,11 +26,11 @@ public class WriterTests
         testFile = Path.ChangeExtension(testFile, "xlsx");
 
         const string worksheetName = "Test";
-        var writer = new ExcelWriter(testFile);
+        using var writer = new ExcelWriter(testFile);
         writer.Write(arrayOfThree, worksheetName);
         writer.SaveAs(testFile);
 
-        var reader = new ExcelReader(testFile);
+        using var reader = new ExcelReader(testFile);
         var readArray = reader.Read<Test>(worksheetName).ToArray();
         Assert.Equal(3, readArray.Length);
 
@@ -40,8 +40,8 @@ public class WriterTests
         writer.Write(listOfTwo, worksheetName, true);
         writer.SaveAs(testFile);
         
-        reader = new ExcelReader(testFile);
-        Assert.Equal(5, reader.Read<Test>(worksheetName).Count());
+        using var newReader = new ExcelReader(testFile);
+        Assert.Equal(5, newReader.Read<Test>(worksheetName).Count());
         File.Delete(testFile);
     }
     
@@ -51,18 +51,18 @@ public class WriterTests
         var testFile = Path.GetRandomFileName();
         testFile = Path.ChangeExtension(testFile, "xlsx");
 
-        var writer = new ExcelWriter(testFile);
+        using var writer = new ExcelWriter(testFile);
         writer.Write(arrayOfThree);
         writer.SaveAs(testFile);
 
-        var reader = new ExcelReader(testFile);
+        using var reader = new ExcelReader(testFile);
         Assert.Equal(arrayOfThree.Length, reader.Read<Test>().Count());
 
         writer.Write(listOfTwo, append: true);
         writer.SaveAs(testFile);
         
-        reader = new ExcelReader(testFile);
-        Assert.Equal(5, reader.Read<Test>().Count());
+        using var newReader = new ExcelReader(testFile);
+        Assert.Equal(5, newReader.Read<Test>().Count());
         File.Delete(testFile);
     }
 
@@ -76,11 +76,11 @@ public class WriterTests
         File.Copy(ForAppend, testFile);
 
         uint headerRowIndex = 3;
-        var writer = new ExcelWriter(testFile);
+        using var writer = new ExcelWriter(testFile);
         writer.Write(arrayOfThree, append: true, headerRowIndex: headerRowIndex);
         writer.SaveAs(testFile);
 
-        var reader = new ExcelReader(testFile);
+        using var reader = new ExcelReader(testFile);
         var readArray = reader.Read<Test>(startFrom: headerRowIndex).ToArray();
         Assert.Equal(6, readArray.Length);
 
@@ -99,11 +99,11 @@ public class WriterTests
         testFile = Path.ChangeExtension(testFile, "xlsx");
         File.Copy(ForAppendHeaderFirst, testFile);
 
-        var writer = new ExcelWriter(testFile);
+        using var writer = new ExcelWriter(testFile);
         writer.Write(arrayOfThree, append: true);
         writer.SaveAs(testFile);
 
-        var reader = new ExcelReader(testFile);
+        using var reader = new ExcelReader(testFile);
         var readArray = reader.Read<Test>().ToArray();
         Assert.Equal(6, readArray.Length);
 
@@ -130,11 +130,11 @@ public class WriterTests
         
         var list = new List<TestTypes>{ expected };
         
-        var writer = new ExcelWriter(testFile);
+        using var writer = new ExcelWriter(testFile);
         writer.Write(list);
         writer.SaveAs(testFile);
 
-        var reader = new ExcelReader(testFile);
+        using var reader = new ExcelReader(testFile);
         var result = reader.Read<TestTypes>().ToList();
         Assert.Single(result);
         var first = result.First();
@@ -161,11 +161,11 @@ public class WriterTests
         testFile = Path.ChangeExtension(testFile, "xlsx");
 
         const string worksheetName = "Test";
-        var writer = new ExcelWriter(testFile);
+        using var writer = new ExcelWriter(testFile);
         writer.Write(arrayWithSkip, worksheetName);
         writer.SaveAs(testFile);
 
-        var reader = new ExcelReader(testFile);
+        using var reader = new ExcelReader(testFile);
         var readArray = reader.Read<TestSkip>(worksheetName).ToArray();
         Assert.Equal(arrayWithSkip.Length, readArray.Length);
 
@@ -192,11 +192,11 @@ public class WriterTests
         testFile = Path.ChangeExtension(testFile, "xlsx");
 
         const string worksheetName = "Test";
-        var writer = new ExcelWriter(testFile);
+        using var writer = new ExcelWriter(testFile);
         writer.Write(arrayWithSkipMiddle, worksheetName);
         writer.SaveAs(testFile);
 
-        var reader = new ExcelReader(testFile);
+        using var reader = new ExcelReader(testFile);
         var readArray = reader.Read<TestSkipMiddle>(worksheetName).ToArray();
         Assert.Equal(arrayWithSkipMiddle.Length, readArray.Length);
 
@@ -223,11 +223,11 @@ public class WriterTests
         var testFile = Path.GetRandomFileName();
         testFile = Path.ChangeExtension(testFile, "xlsx");
 
-        var writer = new ExcelWriter(testFile);
+        using var writer = new ExcelWriter(testFile);
         writer.Write(arrayWithFormulas);
         writer.SaveAs(testFile);
 
-        var reader = new ExcelReader(testFile);
+        using var reader = new ExcelReader(testFile);
         var readArray = reader.Read<TestWithFormula>().ToArray();
         Assert.Equal(arrayWithFormulas.Length, readArray.Length);
 
@@ -252,11 +252,11 @@ public class WriterTests
         var testFile = Path.GetRandomFileName();
         testFile = Path.ChangeExtension(testFile, "xlsx");
 
-        var writer = new ExcelWriter(testFile);
+        using var writer = new ExcelWriter(testFile);
         writer.Write(arrayNumbersWithFormulas);
         writer.SaveAs(testFile);
 
-        var reader = new ExcelReader(testFile);
+        using var reader = new ExcelReader(testFile);
         var readArray = reader.Read<TestNumbersWithFormula>().ToArray();
         Assert.Equal(arrayNumbersWithFormulas.Length, readArray.Length);
 
@@ -282,11 +282,11 @@ public class WriterTests
         var testFile = Path.GetRandomFileName();
         testFile = Path.ChangeExtension(testFile, "xlsx");
 
-        var writer = new ExcelWriter(testFile);
+        using var writer = new ExcelWriter(testFile);
         writer.Write(arrayWithHyperlinks);
         writer.SaveAs(testFile);
 
-        var reader = new ExcelReader(testFile);
+        using var reader = new ExcelReader(testFile);
         var readArray = reader.Read<TestWithHyperlink>().ToArray();
         Assert.Equal(arrayWithFormulas.Length, readArray.Length);
 
@@ -300,4 +300,20 @@ public class WriterTests
         
         File.Delete(testFile);
     }
+
+    [Fact]
+    public void WriteReadInMemory()
+    {
+        using var workbook = new XLWorkbook();
+        const string worksheetName = "Test";
+        using var writer = new ExcelWriter(workbook);
+        writer.Write(arrayOfThree, worksheetName);
+
+        using var reader = new ExcelReader(workbook);
+        var readArray = reader.Read<Test>(worksheetName).ToArray();
+        Assert.Equal(3, readArray.Length);
+
+        for (int i = 0; i < readArray.Length; i++)
+            Assert.Equal(arrayOfThree[i], readArray[i]);
+    }
 }