This article will first outline how the WordApplication class structures a document. Then, it will explain how the InsertXBefore and InsertXAfter methods can be used to insert new content into the document, and will explain how these methods act differently on the various parts of a document.
How WordWriter organizes a Word document
WordWriter represents a Microsoft Word document as a tree, similar to how Word itself represents a document. Most types of elements used with WordApplication correspond to entities that exist in an actual Word document, with some exceptions. Here is the recursive tree structure that WordWriter uses:
Document
|
|--Section
|
|--Paragraph
| |
| |--CharacterRun
| |
| |--InlineImage
| |
| |--Field (includes Hyperlinks and MergeFields)
| |
| |--Field Contents
| |
| |--(Recurses back to Paragraph subtree)
|
|
|--List
| |
| |--ListEntry
| |
| |-(Recurses back to Paragraph subtree)
|
|--Table
|
|-TableCell
|
|-(Recurses back to Section subtree)
The "Recurses back to ..." comments mean that the branch can continue with the same structure of elements as previously defined in the tree. For example, a TableCell can contain a Paragraph, List, and/or another Table, followed by the children those elements support, and so on.
As mentioned previously, not all elements in WordApplication correspond to actual elements in a Word document. For example, the Word file format does not have a list structure. A list item is simply a specialized paragraph with additional formatting. The List type was added to WordApplication to make it easier to work with lists programmatically.
By default, a new Document created using WordApplication.Create contains the following elements:
Document
|
|--Section
|
|--Paragraph
|
|--CharacterRun
Inserting elements using WordApplication
Each of the elements listed in the tree inherit from the Element class, which provides most of the methods for inserting new elements into a document. WordApplication will allow you to call any Insert method on almost any type of element, but the behavior of that method will change depending on what type of element the method is called on and what type of element the method is inserting.
Note the behavior of the following:
- Inserting a new Section also inserts a new Paragraph and CharacterRun within that Section.
- Inserting a new Paragraph also inserts a new CharacterRun within that Paragraph.
Example: Calling InsertCharacterRunAfter on a Section
This example shows the behavior of WordWriter when inserting an element two levels deeper than the current element.
A CharacterRun must be the child of a Paragraph, but InsertTextAfter can be called on a Section. In this case, a new CharacterRun will be inserted at the end of the last Paragraph in the Section.
|
[C#]
|
[VB.NET]
|
|
//--- doc is a Document object
Section sec = doc.Sections[0];
sec.InsertTextAfter(" New text.", true);
'--- doc is a Document object
Dim sec As Section = doc.Sections(0)
sec.InsertTextAfter(" New text.", True)
|
*** To achieve the most predictable behavior, it is recommended practice to call a Create or Insert method on an object appropriate to what is being inserted. ***
So, for example, instead of calling InsertTextAfter on a Section object as described above, it should be called on a Paragraph, ListEntry, or field contents.
|
[C#]
|
[VB.NET]
|
|
//--- doc is a Document object
Section sec = doc.Sections[0];
Element[] paragraphs = sec.get_Elements(Element.Type.Paragraph);
Paragraph lastParagraph = (Paragraph)paragraphs[paragraphs.Length - 1];
lastParagraph.InsertTextAfter(" New text.", true);
'--- doc is a Document object
Dim sec As Section = doc.Sections(0)
Dim paragraphs As Element[] = sec.Elements(Element.Type.Paragraph)
Dim lastParagraph = CType(paragraphs(paragraphs.Length - 1), Paragraph)
lastParagraph.InsertTextAfter(" New text.", True)
|
Here is an example Word document before running either of the code samples above:

Here is the Word document after the code has been run:

Insert behaviors
The following table lists some common examples of how WordWriter behaves when a Create or Insert method is called on different elements.
Each column represents the following:
- Parent element: Element on which InsertXBefore or InsertXAfter is called.
- Element to be inserted: Type of element which is being inserted. Use the appropriate InsertXBefore or InsertXAfter for this type.
- InsertXBefore Behavior: What the InsertXBefore method does in this case.
- InsertXAfter Behavior: What the InsertXAfter method does in this case.
Notes:
- To insert a Section, use CreateSectionBefore or CreateSectionAfter.
- To insert a CharacterRun, use InsertTextBefore or InsertTextAfter.
| Parent element |
Element to be inserted |
InsertXBefore Behavior |
InsertXAfter Behavior |
| Document |
Section |
New Section is inserted before existing Sections. |
New Section is inserted after existing Sections. |
| Document |
Paragraph, List, or Table |
Element is inserted in the first Section of the document before any existing elements in that Section. |
Element is inserted in the last Section of the document after any existing elements in that Section. |
| Document |
CharacterRun, InlineImage, Hyperlink, or MergeField |
Element is inserted in the first element (Paragraph, List, or Table) of the first Section of the document before any existing elements in that first element. |
Element is inserted in the last element (Paragraph, List, or Table) of the last Section of the document after any existing elements in that last element. |
| Section |
Section |
New Section is inserted before the current Section. |
New Section is inserted after the current Section. |
| Section |
CharacterRun, InlineImage, Hyperlink, or MergeField |
Element is inserted in the first element (Paragraph, List, or Table) of this Section before any existing elements in that first element. |
Element is inserted in the last element (Paragraph, List, or Table) of this Section after any existing elements in that last element. |
| List |
List |
New List is inserted before the current List. |
New List is inserted after the current List. |
| List |
CharacterRun, InlineImage, Hyperlink, or MergeField |
Element is inserted in the first ListEntry of the List before any existing elements in that ListEntry. |
Element is inserted in the last ListEntry of the List after any existing elements in that ListEntry. |
| Table |
Table |
Table is inserted in the first TableCell of the current Table before any existing elements in that TableCell. |
There is currently an issue with this behavior. New rows are appended to the current Table instead of being added to a new Table. |
| Table |
Paragraph |
Paragraph is inserted in the first TableCell of the current Table before any existing elements in that TableCell. |
Paragraph is inserted after the Table. |
| Table |
List |
List is inserted before the Table. |
There is currently an issue with this behavior. The List is inserted after the Table and appears as a TableCell. |
| Table |
CharacterRun, InlineImage, Hyperlink, or MergeField |
Element is inserted in the first element (Paragraph, List, or Table) of the first TableCell of the Table before any existing elements in that first element. |
Element is inserted in the next element (Paragraph, List, or Table) after the Table, after any existing elements in that next element. |
|