diff --git a/Mail-Merge/Generate-invoices-from-xml-data/.NET/Generate-invoices-from-xml-data.sln b/Mail-Merge/Generate-invoices-from-xml-data/.NET/Generate-invoices-from-xml-data.sln new file mode 100644 index 000000000..d7892c4aa --- /dev/null +++ b/Mail-Merge/Generate-invoices-from-xml-data/.NET/Generate-invoices-from-xml-data.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.14.36518.9 d17.14 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Generate-invoices-from-xml-data", "Generate-invoices-from-xml-data\Generate-invoices-from-xml-data.csproj", "{DE5C1DFA-6686-4D2C-878A-B0BC60558FF8}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {DE5C1DFA-6686-4D2C-878A-B0BC60558FF8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DE5C1DFA-6686-4D2C-878A-B0BC60558FF8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DE5C1DFA-6686-4D2C-878A-B0BC60558FF8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DE5C1DFA-6686-4D2C-878A-B0BC60558FF8}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {74001C0A-D635-46A4-AF4A-401D245EF6AA} + EndGlobalSection +EndGlobal diff --git a/Mail-Merge/Generate-invoices-from-xml-data/.NET/Generate-invoices-from-xml-data/Data/InvoiceDetails.xml b/Mail-Merge/Generate-invoices-from-xml-data/.NET/Generate-invoices-from-xml-data/Data/InvoiceDetails.xml new file mode 100644 index 000000000..9b73963a5 --- /dev/null +++ b/Mail-Merge/Generate-invoices-from-xml-data/.NET/Generate-invoices-from-xml-data/Data/InvoiceDetails.xml @@ -0,0 +1,52 @@ + + + + 12345 + 2025-04-28 + John Doe + + 1 + SKU123 + Product A + 100.00 + + + 2 + SKU124 + Product B + 200.00 + + + 3 + SKU125 + Product C + 200.00 + + 500.00 + + + 10295 + 2025-04-20 + Paul Henriot + + 1 + SKU123 + Product D + 150.00 + + + 2 + SKU124 + Product E + 200.00 + + + 3 + SKU125 + Product F + 220.00 + + 570.00 + + + diff --git a/Mail-Merge/Generate-invoices-from-xml-data/.NET/Generate-invoices-from-xml-data/Data/Template.docx b/Mail-Merge/Generate-invoices-from-xml-data/.NET/Generate-invoices-from-xml-data/Data/Template.docx new file mode 100644 index 000000000..65f2e7d90 Binary files /dev/null and b/Mail-Merge/Generate-invoices-from-xml-data/.NET/Generate-invoices-from-xml-data/Data/Template.docx differ diff --git a/Mail-Merge/Generate-invoices-from-xml-data/.NET/Generate-invoices-from-xml-data/Generate-invoices-from-xml-data.csproj b/Mail-Merge/Generate-invoices-from-xml-data/.NET/Generate-invoices-from-xml-data/Generate-invoices-from-xml-data.csproj new file mode 100644 index 000000000..21b2f38aa --- /dev/null +++ b/Mail-Merge/Generate-invoices-from-xml-data/.NET/Generate-invoices-from-xml-data/Generate-invoices-from-xml-data.csproj @@ -0,0 +1,28 @@ + + + + Exe + net8.0 + Generate_invoices_from_xml_data + enable + enable + + + + + + + + + + Always + + + Always + + + Always + + + + diff --git a/Mail-Merge/Generate-invoices-from-xml-data/.NET/Generate-invoices-from-xml-data/Output/.gitkeep b/Mail-Merge/Generate-invoices-from-xml-data/.NET/Generate-invoices-from-xml-data/Output/.gitkeep new file mode 100644 index 000000000..5f282702b --- /dev/null +++ b/Mail-Merge/Generate-invoices-from-xml-data/.NET/Generate-invoices-from-xml-data/Output/.gitkeep @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/Mail-Merge/Generate-invoices-from-xml-data/.NET/Generate-invoices-from-xml-data/Program.cs b/Mail-Merge/Generate-invoices-from-xml-data/.NET/Generate-invoices-from-xml-data/Program.cs new file mode 100644 index 000000000..15c7b0ef2 --- /dev/null +++ b/Mail-Merge/Generate-invoices-from-xml-data/.NET/Generate-invoices-from-xml-data/Program.cs @@ -0,0 +1,77 @@ +using Syncfusion.DocIO.DLS; +using System.Dynamic; +using System.Xml; + +namespace Generate_invoices_from_xml_data +{ + class Program + { + public static void Main(string[] args) + { + // Load the template Word document + WordDocument document = new WordDocument(Path.GetFullPath(@"Data/Template.docx")); + // To start each record at new page, so enable this property + document.MailMerge.StartAtNewPage = true; + // Perform the mail merge for the group + document.MailMerge.ExecuteNestedGroup(GetRelationalData()); + // Save the result Word document. + document.Save(Path.GetFullPath("../../../Output/Output.docx")); + // Close the Word document + document.Close(); + } + #region Helper Method + static MailMergeDataTable GetRelationalData() + { + //Gets data from XML + Stream xmlStream = File.OpenRead(Path.GetFullPath(@"Data/InvoiceDetails.xml")); + XmlDocument xmlDocument = new XmlDocument(); + xmlDocument.Load(xmlStream); + xmlStream.Dispose(); + + ExpandoObject customerDetails = new ExpandoObject(); + GetDataAsExpandoObject((xmlDocument as XmlNode).LastChild, ref customerDetails); + // Treat customerDetails as a dictionary + IDictionary customerDict = customerDetails as IDictionary; + // Get the "Invoices" list + List invoicesList = customerDict["Invoices"] as List; + // Take the first item in that list + IDictionary firstInvoiceGroup = invoicesList[0] as IDictionary; + // Get the "Invoice" list from that group + List invoices = firstInvoiceGroup["Invoice"] as List; + //Creates an instance of "MailMergeDataTable" by specifying mail merge group name and "IEnumerable" collection + MailMergeDataTable dataTable = new MailMergeDataTable("Invoices", invoices); + return dataTable; + } + /// + /// Gets the data as ExpandoObject. + /// + /// The reader. + /// + /// reader + /// Unexpected xml tag + reader.LocalName + private static void GetDataAsExpandoObject(XmlNode node, ref ExpandoObject dynamicObject) + { + if (node.InnerText == node.InnerXml) + dynamicObject.TryAdd(node.LocalName, node.InnerText); + else + { + List childObjects; + if ((dynamicObject as IDictionary).ContainsKey(node.LocalName)) + childObjects = (dynamicObject as IDictionary)[node.LocalName] as List; + else + { + childObjects = new List(); + dynamicObject.TryAdd(node.LocalName, childObjects); + } + ExpandoObject childObject = new ExpandoObject(); + foreach (XmlNode childNode in (node as XmlNode).ChildNodes) + { + GetDataAsExpandoObject(childNode, ref childObject); + } + childObjects.Add(childObject); + } + } + #endregion + } +} +