Skip to content

Commit 2ea3b51

Browse files
committed
add support for if statements inside templates
1 parent de67aea commit 2ea3b51

3 files changed

Lines changed: 160 additions & 1 deletion

File tree

13.8 KB
Binary file not shown.

src/MiniWord/MiniWord.Implment.cs

Lines changed: 128 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,9 @@ private static void Generate(this OpenXmlElement xmlElement, WordprocessingDocum
8282
var dicKey = $"{listKey}.{e.Key}";
8383
dic.Add(dicKey, e.Value);
8484
}
85-
85+
86+
ReplaceStatements(xmlElement, tags);
87+
8688
ReplaceText(newTr, docx, tags: dic);
8789
table.Append(newTr);
8890
}
@@ -92,6 +94,8 @@ private static void Generate(this OpenXmlElement xmlElement, WordprocessingDocum
9294
}
9395
}
9496
}
97+
98+
ReplaceStatements(xmlElement, tags);
9599

96100
ReplaceText(xmlElement, docx, tags);
97101
}
@@ -186,6 +190,129 @@ private static List<string> GetReplaceKeys(Dictionary<string, object> tags)
186190
return keys;
187191
}
188192

193+
private static void ReplaceStatements(OpenXmlElement xmlElement, Dictionary<string, object> tags)
194+
{
195+
var paragraphs = xmlElement.Descendants<Paragraph>().ToList();
196+
197+
while (paragraphs.Any(s => s.InnerText.Contains("@if")))
198+
{
199+
var ifIndex = paragraphs.FindIndex(0, s => s.InnerText.Contains("@if"));
200+
var endIfFinalIndex = paragraphs.FindIndex(ifIndex, s => s.InnerText.Contains("@endif"));
201+
202+
var statement = paragraphs[ifIndex].InnerText.Split(' ');
203+
204+
var checkStatement = EvaluateStatement(tags[statement[1]], statement[2], statement[3]);
205+
206+
if (checkStatement)
207+
{
208+
for (int i = ifIndex+1; i <= endIfFinalIndex-1; i++)
209+
{
210+
paragraphs[i].Remove();
211+
}
212+
}
213+
214+
paragraphs[ifIndex].Remove();
215+
paragraphs[endIfFinalIndex].Remove();
216+
217+
paragraphs = xmlElement.Descendants<Paragraph>().ToList();
218+
}
219+
}
220+
221+
private static bool EvaluateStatement(object tagValue, string comparisonOperator, string value)
222+
{
223+
var checkStatement = false;
224+
225+
switch (tagValue)
226+
{
227+
case double dtg when double.TryParse(value, out var doubleNumber):
228+
switch (comparisonOperator)
229+
{
230+
case "==":
231+
checkStatement = !dtg.Equals(doubleNumber);
232+
break;
233+
case "!=":
234+
checkStatement = dtg.Equals(doubleNumber);
235+
break;
236+
case ">":
237+
checkStatement = dtg <= doubleNumber;
238+
break;
239+
case "<":
240+
checkStatement = dtg >= doubleNumber;
241+
break;
242+
case ">=":
243+
checkStatement = dtg < doubleNumber;
244+
break;
245+
case "<=":
246+
checkStatement = dtg > doubleNumber;
247+
break;
248+
}
249+
250+
break;
251+
case int itg when int.TryParse(value, out var intNumber):
252+
switch (comparisonOperator)
253+
{
254+
case "==":
255+
checkStatement = !itg.Equals(intNumber);
256+
break;
257+
case "!=":
258+
checkStatement = itg.Equals(intNumber);
259+
break;
260+
case ">":
261+
checkStatement = itg <= intNumber;
262+
break;
263+
case "<":
264+
checkStatement = itg >= intNumber;
265+
break;
266+
case ">=":
267+
checkStatement = itg < intNumber;
268+
break;
269+
case "<=":
270+
checkStatement = itg > intNumber;
271+
break;
272+
}
273+
274+
break;
275+
case DateTime dttg when DateTime.TryParse(value, out var date):
276+
switch (comparisonOperator)
277+
{
278+
case "==":
279+
checkStatement = !dttg.Equals(date);
280+
break;
281+
case "!=":
282+
checkStatement = dttg.Equals(date);
283+
break;
284+
case ">":
285+
checkStatement = dttg <= date;
286+
break;
287+
case "<":
288+
checkStatement = dttg >= date;
289+
break;
290+
case ">=":
291+
checkStatement = dttg < date;
292+
break;
293+
case "<=":
294+
checkStatement = dttg > date;
295+
break;
296+
}
297+
298+
break;
299+
case string stg:
300+
switch (comparisonOperator)
301+
{
302+
case "==":
303+
checkStatement = stg != value;
304+
break;
305+
case "!=":
306+
checkStatement = stg == value;
307+
break;
308+
}
309+
310+
break;
311+
}
312+
313+
return checkStatement;
314+
}
315+
189316
private static void ReplaceText(OpenXmlElement xmlElement, WordprocessingDocument docx, Dictionary<string, object> tags)
190317
{
191318
var paragraphs = xmlElement.Descendants<Paragraph>().ToArray();

tests/MiniWordTests/IssueTests.cs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -626,6 +626,38 @@ public void MiniWordHyperLink_List()
626626
Assert.Contains("<Relationship Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink\" Target=\"https://google1.com\"", relsXml);
627627
}
628628

629+
[Fact]
630+
public void MiniWordIfStatement_FirstIf()
631+
{
632+
var path = PathHelper.GetTempFilePath();
633+
var templatePath = PathHelper.GetFile("TestBasicStatement.docx");
634+
var value = new Dictionary<string, object>()
635+
{
636+
["Name"] = new List<MiniWordHyperLink>(){
637+
new MiniWordHyperLink(){
638+
Url = "https://google.com",
639+
Text = "測試連結22!!"
640+
},
641+
new MiniWordHyperLink(){
642+
Url = "https://google1.com",
643+
Text = "測試連結11!!"
644+
}
645+
},
646+
["Company_Name"] = "MiniSofteware",
647+
["CreateDate"] = new DateTime(2021, 01, 01),
648+
["VIP"] = true,
649+
["Points"] = 123,
650+
["APP"] = "Demo APP",
651+
};
652+
MiniWord.SaveAsByTemplate(path, templatePath, value);
653+
//Console.WriteLine(path);
654+
var docXml = Helpers.GetZipFileContent(path, "word/document.xml");
655+
Assert.Contains("First if chosen: MiniSofteware", docXml);
656+
Assert.DoesNotContain("Second if chosen: MaxiSoftware", docXml);
657+
Assert.Contains("Points are greater than 100", docXml);
658+
Assert.Contains("CreateDate is not less than 2021", docXml);
659+
Assert.DoesNotContain("CreateDate is not greater than 2021", docXml);
660+
}
629661

630662
[Fact]
631663
public void MiniWordHyperLink_Array()

0 commit comments

Comments
 (0)