Pieter van der Westhuizen

Working with multiple Microsoft Word documents: C# add-in example

In today’s article we’ll take a look at how you can combine information and text from various existing Microsoft Word documents into a single document. We’ll create a Word add-in that will allow the user to select and insert different paragraphs from one or more existing Word documents, into another document. To insert a paragraph into the current document, all the user needs to do is double-click on it in the list of existing paragraphs.

Creating the Word COM add-in project

Start by creating a new ADX COM Add-in in Visual Studio using Add-in Express for Office and .net.

Creating a new Word COM Add-in in Visual Studio

The “New Microsoft Office COM Add-in” project wizard will start. Select your preferred programming language and the minimum supported Office version your add-in needs to support. I will choose C# and Office 2010 for this add-in, though VB.NET and C++.NET are supported as well.

Selecting the programming language and the minimum supported Office version

Click ‘Next’ and select the supported application, which in this scenario will only be Microsoft Word.

Selecting Microsoft Word as the only supported application

Adding an advanced Word task pane

Next, add a new ADX Task pane to your Word add-in project, which is an advanced version-neutral Office task pane that supports all versions of Word, from 2000 to 2013.

Adding an advanced task pane to the Word add-in project

The custom task pane will form the main UI for our Word add-in and will contain a list view control to list all the selected Word documents, a button to add a new document as well as another list view control that will display all the paragraphs in the selected Word document.

The final design of the custom task pane, should resemble the following image:

The final design of the custom task pane

Adding code for adding a new Word document

With the task pane open in the Visual Studio designer, double-click the Add Document button to generate a Click event handler stub. Add the following code to the event handler:

private void btnAddDocument_Click(object sender, EventArgs e)
{
    if (diagOpen.ShowDialog() == DialogResult.OK)
    {
        ListViewItem itemDoc = new ListViewItem(diagOpen.SafeFileName, 0);
        itemDoc.Tag = diagOpen.FileName;
        lvDocs.Items.Add(itemDoc);
    }
}

The code listed above will open a file dialog, with which the user can select a MS Word document. The OpenFileDialog component is a standard Windows Form component I’ve added to the task pane control earlier.

Getting a list of all paragraphs in a document

Next, we need to add code to show a list of paragraphs when the user clicks on the document in the documents list view. To do this, double-click on the first list view we’ve added, to generate a method stub for its SelectedIndexChanged event:

private void lvDocs_SelectedIndexChanged(object sender, EventArgs e)
{
    Word.Application wordApp = null;
    Word.Documents documents = null;
    Word.Document doc = null;
    Word.Paragraphs paragraphs = null;
    Word.Paragraph paragraph = null;
    Word.Range paragraphRange = null;
    ListViewItem selectedItem = null;
    string documentPath = String.Empty;
    bool isVisible = false;
    object missingType = Type.Missing;
 
    try
    {
        if (lvDocs.SelectedItems.Count == 0) return;
        selectedItem = lvDocs.SelectedItems[0];
        documentPath = selectedItem.Tag.ToString();
 
        wordApp = (Word.Application)this.WordAppObj;
        wordApp.ScreenUpdating = false;
        try
        {
            documents = wordApp.Documents;
            doc = documents.Open(documentPath, missingType, missingType,
                missingType, missingType, missingType, missingType,
                missingType, missingType, missingType, missingType,
                isVisible);
 
            paragraphs = doc.Paragraphs;
            lvParagraphs.Items.Clear();
            for (int i = 1; i <= paragraphs.Count; i++)
            {
                paragraph = paragraphs[i];
                paragraphRange = paragraph.Range;
                ListViewItem lvItemParagraph = 
                    new ListViewItem(paragraphRange.Text, 1);
                lvItemParagraph.Tag = documentPath;
                lvParagraphs.Items.Add(lvItemParagraph);
            }
            doc.Close();
        }
        finally
        {
            wordApp.ScreenUpdating = true;
        }
    }
    finally
    {
        if (paragraphRange != null) Marshal.ReleaseComObject(paragraphRange);
        if (paragraph != null) Marshal.ReleaseComObject(paragraph);
        if (paragraphs != null) Marshal.ReleaseComObject(paragraphs);
        if (doc != null) Marshal.ReleaseComObject(doc);
        if (documents != null) Marshal.ReleaseComObject(documents);
    }
}

Inserting an existing paragraph into a document

Lastly, when the user double-clicks on one of the paragraphs listed in the list view, it should be added to the current document. Create an event handler for the paragraphs list view by selecting it and double-clicking next to its DoubleClick event in the property window.

Creating an event handler for the paragraphs list view

Add the following code to the DoubleClick event handler:

private void lvParagraphs_DoubleClick(object sender, EventArgs e)
{
    Word.Application wordApp = null;
    Word.Document wordDoc = null;
    Word.Selection selection = null;
    Word.Range selectionRange = null;
    Word.Range endOfParagraphRange = null;
    Word.Hyperlinks selectionHyperlinks = null;
    int endOfParagraphPosition = 0;
    ListViewItem selectedItem = null;
    string paragraphText = string.Empty;
 
    try
    {
        if (lvParagraphs.SelectedItems.Count == 0) return;
 
        selectedItem = lvParagraphs.SelectedItems[0];
        selectedItem.ImageIndex = 2;
        paragraphText = selectedItem.Text;
 
        wordApp = (Word.Application)this.WordAppObj;
        wordDoc = wordApp.ActiveDocument;
        selection = wordApp.Selection;
        selectionHyperlinks = selection.Hyperlinks;
        selectionRange = selection.Range;
        selectionRange.Text = paragraphText;
 
        endOfParagraphPosition = selectionRange.StoryLength - 2;
        endOfParagraphRange = wordDoc.Range(
            endOfParagraphPosition, endOfParagraphPosition);
        selectionHyperlinks.Add(
            endOfParagraphRange, 
            selectedItem.Tag.ToString(), 
            Type.Missing, 
            "Open Source Document", 
            char.ConvertFromUtf32(8594));
    }
    finally
    {
        if (wordDoc != null)
            Marshal.ReleaseComObject(wordDoc);
        if (endOfParagraphRange != null)
            Marshal.ReleaseComObject(endOfParagraphRange);
        if (selectionHyperlinks != null)
            Marshal.ReleaseComObject(selectionHyperlinks);
        if (selectionRange != null)
            Marshal.ReleaseComObject(selectionRange);
        if (selection != null)
            Marshal.ReleaseComObject(selection);
    }
}

The code above will not only insert the paragraph into the document, but also add a hyperlink to the end of the paragraph linking back to the source document. This is accomplished by using the Add method of the Document objects’ Hyperlinks collection.

Testing the Word add-in

Build, register and run your Word addin project. The final result should be similar to the following image:

The Document Builder add-in in Word 2013

Thank you for reading. Until next time, keep coding!

Available downloads:

This sample Word add-in was developed using Add-in Express for Office and .net:

C# Document Builder add-in for Word

Word add-in development in Visual Studio for beginners:

Post a comment

Have any questions? Ask us right now!