From ce34703e2f5d9cccd90519918362a6ee06a7962d Mon Sep 17 00:00:00 2001 From: Michele Bastione Date: Thu, 26 Feb 2026 23:51:33 +0100 Subject: [PATCH 1/2] Changed logic behind special template cell values identification Changed the logic for identifying special values like `@group` from a Contains check performed on the whole row to an exact match check evaluated on each cell's inner text, thus eliminating the possibility of similar values being misidentified when part of larger text --- .../Templates/OpenXmlTemplate.Impl.cs | 27 ++++++++++++++----- 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/src/MiniExcel.OpenXml/Templates/OpenXmlTemplate.Impl.cs b/src/MiniExcel.OpenXml/Templates/OpenXmlTemplate.Impl.cs index 6eca0286..f77e922d 100644 --- a/src/MiniExcel.OpenXml/Templates/OpenXmlTemplate.Impl.cs +++ b/src/MiniExcel.OpenXml/Templates/OpenXmlTemplate.Impl.cs @@ -377,7 +377,23 @@ await writer.WriteAsync($"<{prefix}sheetData>" var rowInfo = _xRowInfos[rowNo]; var row = rowInfo.Row; - if (row.InnerText.Contains("@group")) + string specialCellType = ""; + foreach (XmlNode c in row.GetElementsByTagName("c")) + { + specialCellType = c.InnerText switch + { + "@group" => "group", + "@endgroup" => "endgroup", + "@merge" or "@endmerge" => "merge", + ['@','h','e','a','d','e','r', ..] => "header", + _ => "" + }; + + if (!string.IsNullOrEmpty(specialCellType)) + break; + } + + if (specialCellType == "group") { groupingStarted = true; hasEverGroupStarted = true; @@ -386,7 +402,7 @@ await writer.WriteAsync($"<{prefix}sheetData>" prevHeader = ""; continue; } - else if (row.InnerText.Contains("@endgroup")) + else if (specialCellType == "endgroup") { if (cellIEnumerableValuesIndex >= cellIEnumerableValues.Count - 1) { @@ -403,13 +419,13 @@ await writer.WriteAsync($"<{prefix}sheetData>" isFirstRound = false; continue; } - else if (row.InnerText.Contains("@header")) + else if (specialCellType == "header") { isHeaderRow = true; } else if (mergeCells) { - if (row.InnerText.Contains("@merge") || row.InnerText.Contains("@endmerge")) + if (specialCellType == "merge") { mergeRowCount++; continue; @@ -418,8 +434,7 @@ await writer.WriteAsync($"<{prefix}sheetData>" if (groupingStarted && !isCellIEnumerableValuesSet) { - cellIEnumerableValues = rowInfo.CellIlListValues - ?? rowInfo.CellIEnumerableValues.Cast().ToList(); + cellIEnumerableValues = rowInfo.CellIlListValues ?? rowInfo.CellIEnumerableValues.Cast().ToList(); isCellIEnumerableValuesSet = true; } From fb184ed29147f8d5271236ea0ff30baf591e9362 Mon Sep 17 00:00:00 2001 From: Michele Bastione Date: Fri, 27 Feb 2026 00:03:26 +0100 Subject: [PATCH 2/2] Minor adjustment --- src/MiniExcel.OpenXml/Templates/OpenXmlTemplate.Impl.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/MiniExcel.OpenXml/Templates/OpenXmlTemplate.Impl.cs b/src/MiniExcel.OpenXml/Templates/OpenXmlTemplate.Impl.cs index f77e922d..3301b699 100644 --- a/src/MiniExcel.OpenXml/Templates/OpenXmlTemplate.Impl.cs +++ b/src/MiniExcel.OpenXml/Templates/OpenXmlTemplate.Impl.cs @@ -385,7 +385,7 @@ await writer.WriteAsync($"<{prefix}sheetData>" "@group" => "group", "@endgroup" => "endgroup", "@merge" or "@endmerge" => "merge", - ['@','h','e','a','d','e','r', ..] => "header", + var s when s.StartsWith("@header") => "header", _ => "" };