/// <summary> /// Recursively searches the composite node for fields and constructs a hierarchical organization of those fields. /// </summary> /// <param name="compositeNode">A node that can be composed of other nodes.</param> /// <param name="wordFields">A hierarchical list of the Word fields found in the composite node or it's descendants.</param> private static void ParseFields(CompositeNode parentNode, List <WordField> wordFields) { // This will recursively search the document object model for any fields at any depth and constructs a hierarchical organization of the fields // found. Node childNode = parentNode.FirstChild; while (childNode != null) { // Composite nodes will be searched recursively for child fields. if (childNode.IsComposite) { MergeDocument.ParseFields(childNode as CompositeNode, wordFields); } // When a field is identified based on the starting node, a new WordField is generated from the stream of nodes in the document. These fields // classes are easier to manage than an distinguised stream of nodes. if (childNode.NodeType == NodeType.FieldStart) { WordField wordField = WordField.CreateField(childNode as FieldStart); wordFields.Add(wordField); childNode = wordField.FieldEnd; } // Test the next node in the stream for the presence of a field. childNode = childNode.NextSibling; } }
/// <summary> /// Create a MergeDocument. /// </summary> /// <param name="stream">A stream used as a source for this document.</param> public MergeDocument(Stream stream) : base(stream) { // Initialize the object this.dictionary = new Dictionary <string, object>(); this.fields = new List <WordField>(); // Recursively parse the fields out of the document MergeDocument.ParseFields(this, this.fields); }
/// <summary> /// Creates a mail merged document from a template and a collection of merge fields. /// </summary> /// <param name="sourceDocument">Byte array representation of a docx document.</param> /// <param name="dictionary">Dictionary list of mail merge parameters.</param> public MemoryStream CreateDocument(Byte[] sourceDocument, Dictionary <String, Object> dictionary) { // Create a Word Processing Document Object Model from the DOCX source. MemoryStream sourceStream = new MemoryStream(sourceDocument); MergeDocument mergeDocument = new MergeDocument(sourceStream); mergeDocument.Dictionary = dictionary; // This will evaluate all the fields in the document using the data dictionary supplied. mergeDocument.Evaluate(); // Now that the mail merge is completed, export the DOCX file to a PDF format. MemoryStream destinationStream = new MemoryStream(); mergeDocument.Save(destinationStream, SaveFormat.Pdf); return(destinationStream); }