From d284942bb00a05fba83d7c4e0fb4f8fb723d326f Mon Sep 17 00:00:00 2001 From: Johan Appelgren Date: Wed, 27 May 2026 11:51:33 +0200 Subject: [PATCH] Fix MergeCells returning null for XLS files without merged cells XlsWorksheet only assigned MergeCells when the file contained merge cells, leaving it null for files with none. CsvWorksheet also returned null. XLSX and XLSB always return an empty array, so this was an inconsistency. Since null carries no extra meaning over an empty array, make all implementations consistent: always return an empty array. Calling AsDataSet with FillMergedCellsValue = true on files without merged cells (including all CSV files) previously threw ArgumentNullException. This fixes the crash. --- .../ExcelCsvReaderTest.cs | 17 +++++++++++++++++ src/ExcelDataReader.Tests/ExcelTestBase.cs | 18 ++++++++++++++++++ .../Core/BinaryFormat/XlsWorksheet.cs | 3 +-- .../Core/CsvFormat/CsvWorksheet.cs | 2 +- src/ExcelDataReader/IExcelDataReader.cs | 2 +- 5 files changed, 38 insertions(+), 4 deletions(-) diff --git a/src/ExcelDataReader.Tests/ExcelCsvReaderTest.cs b/src/ExcelDataReader.Tests/ExcelCsvReaderTest.cs index b9dfad25..3355fffd 100644 --- a/src/ExcelDataReader.Tests/ExcelCsvReaderTest.cs +++ b/src/ExcelDataReader.Tests/ExcelCsvReaderTest.cs @@ -1,3 +1,4 @@ +using System.Data; using System.Text; namespace ExcelDataReader.Tests; @@ -594,4 +595,20 @@ public void Issue614_BackslashEscapedQuote() Assert.That(row, Is.EqualTo(new object[] { "John", "Doe", "120 any st.", "\"Anytown\", WW", "08123" })); } + + [Test] + public void FillMergedCellsValueDoesNotCrashOnCsv() + { + using var excelReader = ExcelReaderFactory.CreateCsvReader(Configuration.GetTestWorkbook(Path.Combine("csv", "comma_in_quotes.csv"))); + DataSet result = excelReader.AsDataSet(new ExcelDataSetConfiguration + { + ConfigureDataTable = _ => new ExcelDataTableConfiguration + { + FillMergedCellsValue = true + } + }); + + Assert.That(result, Is.Not.Null); + Assert.That(result.Tables[0].Rows.Count, Is.EqualTo(2)); + } } \ No newline at end of file diff --git a/src/ExcelDataReader.Tests/ExcelTestBase.cs b/src/ExcelDataReader.Tests/ExcelTestBase.cs index 4f7dccee..66ab745f 100644 --- a/src/ExcelDataReader.Tests/ExcelTestBase.cs +++ b/src/ExcelDataReader.Tests/ExcelTestBase.cs @@ -1097,6 +1097,24 @@ public void AsDataSetTestFillEmptyCellsInMergedRangeUseHeaderRow() Assert.That(result.Tables[0].Rows[5][1], Is.EqualTo("Merge Cell 4")); Assert.That(result.Tables[0].Rows[5][2], Is.EqualTo("Merge Cell 4")); } + + [Test] + public void AsDataSetFillMergedCellsValueWithNoMergeCells() + { + using IExcelDataReader excelReader = OpenReader("10x10"); + DataSet result = excelReader.AsDataSet(new ExcelDataSetConfiguration + { + ConfigureDataTable = _ => new ExcelDataTableConfiguration + { + UseHeaderRow = true, + FillMergedCellsValue = true + } + }); + + Assert.That(result, Is.Not.Null); + Assert.That(result.Tables[0].Rows.Count, Is.EqualTo(9)); + Assert.That(result.Tables[0].Columns.Count, Is.EqualTo(10)); + } protected IExcelDataReader OpenReader(string name) { diff --git a/src/ExcelDataReader/Core/BinaryFormat/XlsWorksheet.cs b/src/ExcelDataReader/Core/BinaryFormat/XlsWorksheet.cs index 48a2f321..8b7a48c3 100644 --- a/src/ExcelDataReader/Core/BinaryFormat/XlsWorksheet.cs +++ b/src/ExcelDataReader/Core/BinaryFormat/XlsWorksheet.cs @@ -650,8 +650,7 @@ private void ReadWorksheetGlobals() Workbook.AddNumberFormat(biffFormat.Key, biffFormat.Value.GetValue(Encoding)); } - if (mergeCells.Count > 0) - MergeCells = mergeCells.ToArray(); + MergeCells = mergeCells.ToArray(); if (!SinglePassMode) { diff --git a/src/ExcelDataReader/Core/CsvFormat/CsvWorksheet.cs b/src/ExcelDataReader/Core/CsvFormat/CsvWorksheet.cs index 567bc4ba..d54617a1 100644 --- a/src/ExcelDataReader/Core/CsvFormat/CsvWorksheet.cs +++ b/src/ExcelDataReader/Core/CsvFormat/CsvWorksheet.cs @@ -49,7 +49,7 @@ public CsvWorksheet(Stream stream, Encoding fallbackEncoding, char[] autodetectS public HeaderFooter HeaderFooter => null; - public CellRange[] MergeCells => null; + public CellRange[] MergeCells => []; public int FieldCount { get; } diff --git a/src/ExcelDataReader/IExcelDataReader.cs b/src/ExcelDataReader/IExcelDataReader.cs index 15977d23..65869e2b 100644 --- a/src/ExcelDataReader/IExcelDataReader.cs +++ b/src/ExcelDataReader/IExcelDataReader.cs @@ -38,7 +38,7 @@ public interface IExcelDataReader : IDataReader HeaderFooter HeaderFooter { get; } /// - /// Gets the list of merged cell ranges. + /// Gets the list of merged cell ranges, or an empty array if there are none. /// CellRange[] MergeCells { get; }