3 November, 2013
2 Comments
1 category
Create a new Microsoft Word document add two content controls with the names:
- Employee_Firstname
- Employee_Lastname
Like:
Employee_Lastname
Now when you run the unittest below, the following the result will be:
namespace EndToEndTest { using DocumentFormat.OpenXml; using DocumentFormat.OpenXml.CustomXmlDataProperties; using DocumentFormat.OpenXml.Packaging; using DocumentFormat.OpenXml.Wordprocessing; using Microsoft.VisualStudio.TestTools.UnitTesting; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Xml; using System.Xml.Linq; [TestClass] public class RliResearch { private List<string> _tagNames = new List<string>(); private List<string> _uniqueTagNames = new List<string>(); [TestMethod] public void Test_with_duration() { var watch = new System.Diagnostics.Stopwatch(); watch.Start(); InitialiseDatabinding(); watch.Stop(); System.Console.WriteLine(watch.Elapsed.TotalMilliseconds); } public void InitialiseDatabinding() { using (WordprocessingDocument doc = WordprocessingDocument.Open(@"C:\Temp\Test.docx", true)) { CustomXmlPart customXmlPart = doc.MainDocumentPart.CustomXmlParts.FirstOrDefault(); if (customXmlPart == null) { customXmlPart = doc.MainDocumentPart.AddCustomXmlPart(CustomXmlPartType.CustomXml); } if (customXmlPart.CustomXmlPropertiesPart == null) { customXmlPart.AddNewPart<CustomXmlPropertiesPart>(); } var propertiesPart = customXmlPart.CustomXmlPropertiesPart; if(propertiesPart.DataStoreItem == null) { var dataStoreItem = new DataStoreItem() { ItemId = Guid.NewGuid().ToString("B") }; propertiesPart.DataStoreItem = dataStoreItem; } string dataStoreId = customXmlPart.CustomXmlPropertiesPart.DataStoreItem.ItemId; var names = new List<string>(); foreach (var cc in doc.ContentControls()) { SdtProperties props = cc.Elements<SdtProperties>().FirstOrDefault(); if (props != null) { string name = string.Empty; try { Tag tag = props.Elements<Tag>().FirstOrDefault(); if (tag != null) { name = tag.Val.ToString(); names.Add(name); tag.Val = name; DocumentFormat.OpenXml.Wordprocessing.SdtAlias alias = props.Elements<DocumentFormat.OpenXml.Wordprocessing.SdtAlias>().FirstOrDefault(); if (alias != null) { alias.Val = name; } // Update databinding DocumentFormat.OpenXml.Wordprocessing.DataBinding dataBinding = props.Elements<DocumentFormat.OpenXml.Wordprocessing.DataBinding>().FirstOrDefault(); if (dataBinding == null) { dataBinding = new DataBinding(); dataBinding.XPath = string.Format("/Root[1]/{0}[1]", name); dataBinding.StoreItemId = dataStoreId; props.Append(dataBinding); } else { dataBinding.XPath = string.Format("/Root[1]/{0}[1]", name); dataBinding.StoreItemId = dataStoreId; } } } catch (Exception ex) { throw new ApplicationException(string.Format("Exception found during processing of tag [{0}].", name), ex); } } } List<string> uniqueTagNames = names.Distinct(StringComparer.CurrentCultureIgnoreCase).OrderBy(x => x).ToList(); XDocument xdoc = CreateXmlDocument("Root", uniqueTagNames); SaveCustomXmlPart(customXmlPart, xdoc); } } /// <summary> /// Create a XDocument, with a root element based on the given "rootName", containing child elements based on the given "tagnames". /// </summary> public XDocument CreateXmlDocument(string rootName, List<string> tagNames) { var document = new XDocument( new XDeclaration("1.0", "utf-8", null), new XElement(rootName, tagNames.Select(x => { XElement xe = new XElement(x, string.Empty); if(string.Compare(x, "Employee_Firstname", true) == 0) { xe = new XElement(x, "Johny"); } if (string.Compare(x, "Employee_Lastname", true) == 0) { xe= new XElement(x, "Droptables"); } return xe; } ) ) ); return document; } public void SaveCustomXmlPart(CustomXmlPart part, XDocument xdoc) { using (var stream = part.GetStream(FileMode.Create, FileAccess.ReadWrite)) { // Reset stream position to 0, to prevent errors. stream.Position = 0; using (XmlWriter xw = XmlWriter.Create(stream)) { xdoc.Save(xw); } } } } /// <summary> /// Code from: http://openxmldeveloper.org/blog/b/openxmldeveloper/archive/2011/04/11/137383.aspx /// </summary> public static class ContentControlExtensions { public static IEnumerable<OpenXmlElement> ContentControls( this OpenXmlPart part) { return part.RootElement .Descendants() .Where(e => e is SdtBlock || e is SdtRun); } public static IEnumerable<OpenXmlElement> ContentControls( this WordprocessingDocument doc) { foreach (var cc in doc.MainDocumentPart.ContentControls()) yield return cc; foreach (var header in doc.MainDocumentPart.HeaderParts) foreach (var cc in header.ContentControls()) yield return cc; foreach (var footer in doc.MainDocumentPart.FooterParts) foreach (var cc in footer.ContentControls()) yield return cc; if (doc.MainDocumentPart.FootnotesPart != null) foreach (var cc in doc.MainDocumentPart.FootnotesPart.ContentControls()) yield return cc; if (doc.MainDocumentPart.EndnotesPart != null) foreach (var cc in doc.MainDocumentPart.EndnotesPart.ContentControls()) yield return cc; } } }
Category: Uncategorized
Hi,
I tried the piece of code it works but when i do the same to a document generated ( having content control produced by macro) it fails. I am unable to open the docuemnt. it throws some some in docuemt.xml. Please help me.
Regards,
Patrick CJ
the above code works fine but when combo box and Activex radio buttons are tobe traced its not working. Please give a solution for that.