CustomXmlParts.vb
- ''
- '' This code is part of Document Solutions for Word demos.
- '' Copyright (c) MESCIUS inc. All rights reserved.
- ''
- Imports System.IO
- Imports System.Drawing
- Imports System.Collections.Generic
- Imports System.Linq
- Imports System.Xml
- Imports GrapeCity.Documents.Word
-
- '' This example demonstrates how to create a document with multiple ContentControls,
- '' whose values are mapped to user-created CustomXmlPart file, standart Xml file
- '' which defines various elements And attributes.
- '' This document also contain a header And a footer with elements that are also mapped to
- '' proper xml elements.
- Public Class CustomXmlParts
- Function CreateDocx() As GcWordDocument
- Dim doc = New GcWordDocument()
-
- '' Create custom xml part And keep it in the document
- CreateOrderCustomXmlFromString(doc)
-
- '' Set custom xml document element value
- SetDeliveryOption(doc, True)
-
- '' Compose document with Case properties bound to proper CustomControls
-
- '' Create And map To text field
- CreateOficialBody(doc)
-
- '' Create And map Appeal checkbox And AppealDeadline Text control
- CreateDeliveryCheckbox(doc)
-
- '' Create Header And map Department xml element
- CreateHeaderWithMappedDepartment(doc)
-
- '' Create Header And map document built-in Author xml element
- CreateFooterWithMappedAuthor(doc)
-
- '' Done
- Return doc
- End Function
-
- '' Retrieve a CustomXmlPart from a document by name
- Private Shared Function GetCustomXmlPartByName(ByRef doc As GcWordDocument, ByRef name As String) As CustomXmlPart
- For Each xmlPart In doc.CustomXmlParts
- If String.Compare(xmlPart.XmlDocument.DocumentElement.Name, name, True) = 0 Then
- Return xmlPart
- End If
- Next
- Throw New ArgumentException(String.Format("Could not find custom xml part {0}", name))
- End Function
-
-
- '' Find 'Order' CustomXmlPart and set its DeliveryAppeal xml element to value provided by method parameter:
- Private Shared Sub SetDeliveryOption(ByRef doc As GcWordDocument, ByVal deliveryRequired As Boolean)
- Dim xmlPart = GetCustomXmlPartByName(doc, "Order")
-
- Dim node = xmlPart.XmlDocument.SelectSingleNode("//*[local-name()='Delivery']")
- If deliveryRequired Then
- node.InnerText = "true"
- Else
- node.InnerText = "false"
- End If
- End Sub
-
- '' Compose half of document body, map "To" text custom control to proper CustomXml field
- Private Shared Sub CreateOficialBody(ByRef doc As GcWordDocument)
- Dim p = doc.Body.Paragraphs.Add("Dear ")
- Dim tto = p.GetRange().ContentControls.Add(ContentControlType.Text, False)
- tto.XmlMapping.SetMapping("//grapecity:To", "xmlns:grapecity='http://grapecity.com'")
-
- p.GetRange().Runs.First.Font.Size = 10
- tto.Font.Size = 10
- p.GetRange().Runs.Add(",")
- doc.Body.Paragraphs.Add()
-
- p = doc.Body.Paragraphs.Add(
- "The first shipment of equipment from AMA Ltd has arrived. " +
- "We are delighted with every piece. Therefore, we decided to make " +
- "our initial purchase larger than anticipated. I am attaching our " +
- "purchase order No. 8393 for additional goods. Since you already have " +
- "a copy of our Procurement Guidelines, I shall not attach them to " +
- "this order. Current Shipping date is ")
-
- '' Add shipping Date control, bound to proper section of Order CustomXmlPart:
- Dim dateControl = p.GetRange().ContentControls.Add(ContentControlType.Date, False)
- dateControl.DateFormat = "dd.MM.yyyy"
- ''here we demonstrate how to map CustomControl with namespaces usage, it allows us write
- ''clean And straight XmlPath. Its the right way of XMlMapping
- dateControl.XmlMapping.SetMapping("//grapecity:Delivery/@DeliveryDate",
- "xmlns:grapecity='http://grapecity.com'")
- p.GetRange().Paragraphs.Add(
- "If you want to change it, select checkbox below and change Date, " +
- "then send this letter back to me")
- dateControl.Font.Italic = True
-
- p.GetRange().Runs.First.Font.Size = 12
- p.GetRange().Runs.First.Font.Italic = True
- End Sub
-
- '' Create footer And map Author built-in property to Text content control
- Private Shared Sub CreateFooterWithMappedAuthor(ByRef doc As GcWordDocument)
- Dim footer = doc.Body.Sections.First.Footers(HeaderFooterType.Primary)
- Dim p = footer.Body.Paragraphs.Add("Sincerely yours, ")
-
- If p.Document.Settings.BuiltinProperties.Author Is Nothing Then
- p.Document.Settings.BuiltinProperties.Author = "Nancy Davolio"
- End If
-
- '' Create Text ContentControl And bind its value to builtin Author property:
- Dim authorTextControl = p.GetRange().ContentControls.Add(ContentControlType.Text, False)
-
- '' Use specialized SetMapping overload for document BuiltInProperties.
- '' here we bind (map) ContentControl to builtin Author property:
- authorTextControl.XmlMapping.SetMapping(Function() p.Document.Settings.BuiltinProperties.Author)
- End Sub
-
- '' Create header with Text ContentControl mapped to 'Department' node of 'Order' CustomXml:
- Private Shared Sub CreateHeaderWithMappedDepartment(ByRef doc As GcWordDocument)
- '' Create Header And fill it with data:
- Dim header = doc.Body.Sections.First.Headers(HeaderFooterType.Primary)
- Dim p = header.Body.Paragraphs.Add()
- Dim departmentTextControl = p.GetRange().ContentControls.Add(ContentControlType.Text, False)
-
- '' Get our Case CustomXmlPart:
- Dim xmlPart = GetCustomXmlPartByName(doc, "Order")
-
- Dim departmentNode = xmlPart.XmlDocument.SelectSingleNode("//*[local-name()='Department']")
- '' Mapping directly to XmlNode:
- departmentTextControl.XmlMapping.SetMapping(departmentNode)
- End Sub
-
- '' Create Delivery part, Checkbox custom control bound to Delivery node And Date custom control
- '' bound to details of (possible) Delivery date.
- Private Shared Sub CreateDeliveryCheckbox(ByRef doc As GcWordDocument)
- Dim p = doc.Body.Paragraphs.Add()
-
- '' Create checkbox And map it to Shipping node of 'Case' CustomXmlPart:
- Dim checkBox = p.GetRange().ContentControls.Add(ContentControlType.CheckBox, False)
-
- '' Here we demonstrate how to map CustomControl ignoring namespaces used in the xml.
- '' This way should be avoided as much as possible as pretty inefficient:
- checkBox.XmlMapping.SetMapping("//*[local-name()='Delivery']")
-
- p.GetRange().Runs.Add("Delivery should be done before ")
-
- '' Add shipping Date control, bound to proper section of Order CustomXmlPart:
- Dim dateControl = p.GetRange().ContentControls.Add(ContentControlType.Date, False)
- dateControl.DateFormat = "dd.MM.yyyy"
- '' Here we demonstrate how to map CustomControl with namespaces usage, it allows us write
- '' clean And straight XmlPath. Its the right way of XMlMapping:
- dateControl.XmlMapping.SetMapping("//grapecity:Delivery/@DeliveryDate",
- "xmlns:grapecity='http://grapecity.com'")
- End Sub
-
- '' Create XML from a string (see alternative method below)
- Private Shared Sub CreateOrderCustomXmlFromString(ByRef doc As GcWordDocument)
- Dim sb = New System.Text.StringBuilder(201)
- Const ns = "'http://grapecity.com'"
-
- sb.AppendLine("<Order xmlns=" + ns + ">")
- sb.AppendLine(" <To>Mark Donahue</To>")
- sb.AppendLine(" <Department>Shipping department</Department>")
- sb.AppendLine(" <Delivery DeliveryDate=""12.04.2019"">true</Delivery>")
- sb.AppendLine("</Order>")
-
- Dim xml = New XmlDocument()
- xml.LoadXml(sb.ToString())
- Dim xmlPart = doc.CustomXmlParts.Add(xml, Guid.NewGuid().ToString(), New String() {ns}, "application/xml")
- End Sub
-
- '' Create XML by adding individual nodes one by one
- '' (this method Is Not used in this sample, the previous
- '' alternative Is used instead)
- Private Shared Sub CreateOrderCustomXml(ByRef doc As GcWordDocument)
- '' add a custom xml part with custom settings
- Const ns = "http://grapecity.com"
- Dim xml = New XmlDocument()
-
- xml.AppendChild(xml.CreateXmlDeclaration("1.0", "utf-8", Nothing))
- Dim root = xml.CreateElement("Order", ns)
- xml.AppendChild(root)
-
- Dim tto = root.AppendChild(xml.CreateElement("To", ns))
- tto.InnerText = "Mark Donahue"
-
- Dim dep = root.AppendChild(xml.CreateElement("Department", ns))
- dep.InnerText = "Shipping department"
-
- Dim child = xml.CreateElement("Delivery", ns)
- child.InnerText = "true"
- child.SetAttribute("DeliveryDate", "12.04.2019")
-
- root.AppendChild(child)
-
- Dim xmlPart = doc.CustomXmlParts.Add(xml, Guid.NewGuid().ToString(), New String() {ns}, "application/xml")
-
- '' Sad story: we cannot apply schemas To our custom xml parts.
- '' Unlike in Office excel (where a schema can be serialized inside a document),
- '' it seems that Word can work with schema URIs only so we cannot place an xsd inside the document.
- '' This means that we cannot implement native xml-mapping restrictiong And verifying Like
- '' xmlPart.Schemas.Add(CreateCelebrationScheme())
- End Sub
- End Class
-