Deborah's Developer MindScape






         Tips and Techniques for Web and .NET developers.

Archive for Microsoft Word

August 31, 2009

Bolding Text in Microsoft Word using .NET

Filed under: C#,Microsoft Word,VB.NET @ 1:42 pm

One of the common requirements in working with Microsoft Word from .NET is to bold some text. This is often required to draw attention to specific words within the document.

This code example highlights any instances of the word "was". It can be changed to instead highlight any word you desire.

In C#:

// Add to the top of the code file
using Word = Microsoft.Office.Interop.Word;

// Add to a subroutine
Word.Application Wd;
Word.Document doc;
object missingValue = Missing.Value;

// Start Word and get Application object
Wd = new Word.Application();

// Add a new document
doc = Wd.Documents.Add(ref missingValue,ref missingValue, 
                       ref missingValue,ref missingValue );

// Write some text
Wd.Selection.TypeText("Once upon a time there was a document. " +
                      "The document was fair and fine." +
                      "The document was short.");

// Bold the specified word
foreach (Word.Range w in doc.Words)
{
    if (w.Text.Trim() == "was")
        w.Font.Bold = 1;
}

// Save
object fileName = @"test1.docx";
doc.SaveAs(ref fileName,
            ref missingValue, ref missingValue,
            ref missingValue, ref missingValue,
            ref missingValue, ref missingValue,
            ref missingValue, ref missingValue,
            ref missingValue, ref missingValue,
            ref missingValue, ref missingValue,
            ref missingValue, ref missingValue,
            ref missingValue);

// Close
doc.Close(ref missingValue, ref missingValue, ref missingValue);
doc = null;
Wd.Quit(ref missingValue, ref missingValue, ref missingValue);

// Clean up
// NOTE: When in release mode, this does the trick
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect() ;

In VB:

‘ Add to the top of the code file
Imports Word = Microsoft.Office.Interop.Word

‘ Add to a subroutine
Dim Wd As Word.Application
Dim doc As Word.Document

‘ Start Word and get Application object
Wd = New Word.Application

‘ Add a new document
doc = Wd.Documents.Add

‘ Write some text
Wd.Selection.TypeText("Once upon a time there was a document. " & _
                      "The document was fair and fine." & _
                      "The document was short.")

Bold the specified word
For Each w As Word.Range In doc.Words
    If (w.Text.Trim() = "was") Then
        w.Font.Bold = 1
    End If
Next

‘ Save
doc.SaveAs("test1.docx")

‘ Close
doc.Close()
doc = Nothing
Wd.Quit()

‘ Clean up
‘ NOTE: When in release mode, this does the trick
GC.WaitForPendingFinalizers()
GC.Collect()
GC.WaitForPendingFinalizers()
GC.Collect()

In both of these examples, the code starts Word, creates a new Word document, and writes some text into the document. It then loops through the words in the document and bolds any that match "was". You can, of course, change this to any word.

The code then saves the document. Since no directory was found, it defaults to the My Document folder.

Notice the missingValue variable in the C# code that is not in the VB code. VB supports default parameters, but C# does not. So any time a parameter is defined for a Word method, C# must provide it. VB will use the default parameter values.

NOTE: A new feature in C# 4.0 (Visual Studio 2010) allows for default parameters in C# as well, dramatically simplifying the C# code that interacts with Word or Excel.

Enjoy!

August 14, 2009

Using Linq with Microsoft Word and Excel

Some of the collections in the Microsoft Office object models implement IEnumerable. The IEnumerable interface provides the ability to perform a for/each against the collection. With .NET 3.5, a Cast extension method of IEnumerable allows you to work with these collections using Linq.

Microsoft Word


For example, say you want to bind the set of open Word document names in a ComboBox.

First, set a reference to the desired version of the Microsoft Word Object Library from the COM tab of the Add Reference dialog. The resulting reference appears as Microsoft.Office.Interop.Word.

In C#:

// Add to the top of the code file using Word = Microsoft.Office.Interop.Word;

// Add to a subroutine
Word.Application Wd;
Word.Document doc;
Word.Document doc2;
object missingValue = Missing.Value;

// Start Word and get Application object Wd = new Word.Application();

// Define documents doc = Wd.Documents.Add(ref missingValue,ref missingValue, ref missingValue,ref missingValue ); doc2 = Wd.Documents.Add(ref missingValue, ref missingValue, ref missingValue, ref missingValue);

// Use Linq to access the document names. var query = from d in Wd.Documents.Cast<Word.Document>() select d.Name; comboBox1.DataSource = query.ToList();

// Or use Lambda expressions var query2 = Wd.Documents.Cast<Word.Document>().Select(d=> d.Name); comboBox1.DataSource = query2.ToList();

// Close doc.Close(ref missingValue, ref missingValue, ref missingValue); doc = null; doc2.Close(ref missingValue, ref missingValue, ref missingValue); doc2 = null; Wd.Quit(ref missingValue, ref missingValue, ref missingValue);

// Clean up // NOTE: When in release mode, this does the trick GC.WaitForPendingFinalizers(); GC.Collect(); GC.WaitForPendingFinalizers(); GC.Collect() ;

In VB:

‘ Add to the top of the code file Imports Word = Microsoft.Office.Interop.Word

‘ Add to a subroutine Dim Wd As Word.Application Dim doc As Word.Document Dim doc2 As Word.Document

‘ Start Word and get Application object
Wd = New Word.Application

‘ Define documents doc = Wd.Documents.Add doc2 = Wd.Documents.Add

‘ Use Linq to access the document names. Dim query = From d In Wd.Documents.Cast(Of Word.Document)() _ Select d.Name ComboBox1.DataSource = query.ToList

‘ Or use Lambda expressions Dim query2 = Wd.Documents.Cast(Of Word.Document) _ .Select(Function(d) d.Name) ComboBox1.DataSource = query2.ToList

‘ Close doc.Close() doc = Nothing doc2.Close() doc2 = Nothing Wd.Quit()

‘ Clean up ‘ NOTE: When in release mode, this does the trick GC.WaitForPendingFinalizers() GC.Collect() GC.WaitForPendingFinalizers() GC.Collect()

In both of these examples, the code starts Word, creates two Word documents, uses either Linq or a Lambda expression to define a query and then binds the resulting set of document names to a Combo Box.

Notice the missingValue variable in the C# code that is not in the VB code. VB supports default parameters, but C# does not. So any time a parameter is defined for a Word method, C# must provide it. VB will use the default parameter values.

NOTE: A new feature in C# 4.0 (Visual Studio 2010) allows for default parameters in C# as well, dramatically simplifying the C# code that interacts with Word or Excel.

As another example, the following code retrieves all of the words from the defined Word document.

In C#:

var query = from w in doc.Words.Cast<Word.Range>() select w.Text; comboBox1.DataSource = query.ToList();

In VB:

Dim query = From w In doc.Words.Cast(Of Word.Range)() _ Select w.Text ComboBox1.DataSource = query3.ToList

This code retrieves all of the words in the document defined by the doc variable. Instead of selecting the list of words, you could use any Linq feature such as finding only a specific set of words that match a criteria or counting the number of occurrences of a given word.

Microsoft Excel


This technique works with Excel as well. Say you want to bind the list of spreadsheets in an Excel workbook.

First, set a reference to the desired version of the Microsoft Excel Object Library from the COM tab of the Add Reference dialog. The resulting reference appears as Microsoft.Office.Interop.Excel.

In C#:

// Add to the top of the code file using Excel = Microsoft.Office.Interop.Excel;

// Add to a subroutine Excel.Application oXL; Excel.Workbook oWB; Excel.Worksheet oSheet;

// Start Excel and get Application object. oXL = new Excel.Application();

// Get a new workbook. oWB = oXL.Workbooks.Add(Missing.Value);

// Get the active sheet and change its name oSheet = (Excel.Worksheet)oWB.ActiveSheet ; oSheet.Name = “Test”;

// Use Linq to access the spreadsheet names.
var query = from s in oXL.Worksheets.Cast<Excel.Worksheet>()
select s.Name;
comboBox1.DataSource = query.ToList();

// Or use Lambda expressions. var query2 = oXL.Worksheets.Cast<Excel.Worksheet>() .select(s => s.Name); comboBox1.DataSource = query2.ToList();

// Close oSheet = null; oWB.Close(Missing.Value, Missing.Value, Missing.Value); oWB = null; oXL.Quit();

// Clean up // NOTE: When in release mode, this does the trick GC.WaitForPendingFinalizers(); GC.Collect(); GC.WaitForPendingFinalizers(); GC.Collect();

In VB:

‘ Add to the top of the code file Imports Excel = Microsoft.Office.Interop.Excel

‘ Add to a subroutine Dim oXL As Excel.Application Dim oWB As Excel.Workbook Dim oSheet As Excel.Worksheet

‘ Start Excel and get Application object.
oXL = New Excel.Application

‘ Get a new workbook.
oWB = oXL.Workbooks.Add

‘ Get the active sheet and change its name
oSheet = DirectCast(oWB.ActiveSheet, Excel.Worksheet)
oSheet.Name = “Test”

‘ Use Linq to access the spreadsheet names. Dim query = From s In oXL.Worksheets.Cast(Of Excel.Worksheet)() _ Select s.Name ComboBox1.DataSource = query.ToList

‘ Or use Lambda expressions
Dim query2 = oXL.Worksheets.Cast(Of Excel.Worksheet) _
.Select(Function(s) s.Name)
ComboBox1.DataSource = query2.ToList

‘ Close oSheet = Nothing oWB.Close() oWB = Nothing oXL.Quit()

‘ Clean up
‘ NOTE: When in release mode, this does the trick
GC.WaitForPendingFinalizers()
GC.Collect()
GC.WaitForPendingFinalizers()
GC.Collect()

In both examples, the code starts Excel, changes the name of the active sheet, uses either Linq or a Lambda expression to define a query and then binds the resulting set of sheet names to a Combo Box.

Enjoy!

EDITED 11/16/09: Added information on setting the appropriate reference.

© 2014 Deborah's Developer MindScape   Provided by WPMU DEV -The WordPress Experts   Hosted by Microsoft MVPs