Skip to content

Commit

Permalink
add $= formula handling with $enumrowstart/end placeholder replacments (
Browse files Browse the repository at this point in the history
#621)

Co-authored-by: meld-cp <[email protected]>
  • Loading branch information
meld-cp authored and shps951023 committed Jul 6, 2024
1 parent b3a980c commit 1caf3fe
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 0 deletions.
Binary file not shown.
34 changes: 34 additions & 0 deletions src/MiniExcel/OpenXml/ExcelOpenXmlTemplate.Impl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,10 @@ private void WriteSheetXml(Stream stream, XmlDocument doc, XmlNode sheetData, bo
int rowIndexDiff = 0;
var rowXml = new StringBuilder();

// for formula cells
int enumrowstart = -1;
int enumrowend = -1;

// for grouped cells
bool groupingStarted = false;
bool hasEverGroupStarted = false;
Expand Down Expand Up @@ -410,6 +414,7 @@ private void WriteSheetXml(Stream stream, XmlDocument doc, XmlNode sheetData, bo
{
var first = true;
var iEnumerableIndex = 0;
enumrowstart = newRowIndex;

foreach (var item in rowInfo.CellIEnumerableValues)
{
Expand Down Expand Up @@ -732,14 +737,43 @@ private void WriteSheetXml(Stream stream, XmlDocument doc, XmlNode sheetData, bo

}
}

enumrowend = newRowIndex-1;
}
else
{

// convert cells starting with '$=' into formulas
var cs = row.SelectNodes($"x:c", _ns);
foreach (XmlElement c in cs)
{
/* Target:
<c r="C8" s="3">
<f>SUM(C2:C7)</f>
</c>
*/
var vs = c.SelectNodes($"x:v", _ns);
foreach (XmlElement v in vs)
{
if (!v.InnerText.StartsWith("$="))
{
continue;
}
var fNode = c.OwnerDocument.CreateElement("f", Config.SpreadsheetmlXmlns);
fNode.InnerText = v.InnerText.Substring(2);
c.InsertBefore(fNode, v);
c.RemoveChild(v);
}
}
innerXml = row.InnerXml;

rowXml.Clear()
.Append(outerXmlOpen)
.AppendFormat(@" r=""{0}"">", newRowIndex)
.Append(innerXml)
.Replace($"{{{{$rowindex}}}}", newRowIndex.ToString())
.Replace($"{{{{$enumrowstart}}}}", enumrowstart.ToString())
.Replace($"{{{{$enumrowend}}}}", enumrowend.ToString())
.AppendFormat("</{0}>", row.Name);
writer.Write(CleanXml(rowXml, endPrefix)); // pass StringBuilder for netcoreapp3.0 or above

Expand Down
28 changes: 28 additions & 0 deletions tests/MiniExcelTests/MiniExcelTemplateTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -721,6 +721,34 @@ public void TestIEnumerable()
}
}

[Fact]
public void TestIEnumerableWithFormulas()
{
{
var path = Path.Combine(Path.GetTempPath(), $"{Guid.NewGuid().ToString()}.xlsx");
var templatePath = @"../../../../../samples/xlsx/TestTemplateBasicIEnumerableFillWithFormulas.xlsx";

//1. By POCO
var value = new
{
employees = new[]
{
new {name="Jack",department="HR", salary= 90000},
new {name="Lisa",department="HR", salary=150000},
new {name="John",department="HR", salary= 64000},
new {name="Mike",department="IT", salary= 87000},
new {name="Neo", department="IT", salary= 98000},
new {name="Joan",department="IT", salary=120000}
}
};
MiniExcel.SaveAsByTemplate(path, templatePath, value);

var dimension = Helpers.GetFirstSheetDimensionRefValue(path);
Assert.Equal("A1:C13", dimension);

}
}

[Fact]
public void TemplateTest()
{
Expand Down

0 comments on commit 1caf3fe

Please sign in to comment.