Kahn
Kahn

Reputation: 1660

C# Word Document - How to clean formatting?

The dilemma is rather simple. I need to create a small app that will clear all font background colors (leave table cell background colours unchanged), and remove all text with strikethrough in a word document, and then save the document into another folder. Otherwise the document's formatting should remain untouched.

Below is a large-ish example scraped together from random examples available in google showing how to apply specific kinds of formatting to random strings found using Find.Execute(). I have no clue however, on how to only do as described above.

public static string searchDoc(string fileNameRef)
    {

        Microsoft.Office.Interop.Word._Application word = new Microsoft.Office.Interop.Word.Application(); ;
        Microsoft.Office.Interop.Word._Document doc = new Microsoft.Office.Interop.Word.Document();
        object missing = System.Type.Missing;

        try
        {
            System.IO.FileInfo ExecutableFileInfo =
                    new System.IO.FileInfo(System.Reflection.Assembly.GetEntryAssembly().Location);

            object fileName =
                System.IO.Path.Combine(ExecutableFileInfo.DirectoryName, fileNameRef);

            doc = word.Documents.Open(ref fileName, ref missing, ref missing, ref missing
                , ref missing, ref missing, ref missing, ref missing, ref missing, ref missing
                , ref missing, ref missing, ref missing, ref missing, ref missing, ref missing);
            doc.Activate();

            //object findStr = "hello"; //sonething to find
            // THIS is the part where I fail, I can't find of a way to Find.Execute on formatting
            // as opposed to mere strings.
            //while (word.Selection.Find.Execute(ref findStr))  //found...
            //{
            //    //change font and format of matched words
            //    word.Selection.Font.Name = "Tahoma"; //change font to Tahoma
            //    word.Selection.Font.ColorIndex = Microsoft.Office.Interop.Word.WdColorIndex.wdRed;  //change color to red
            //}

            object saveFileName = ExecutableFileInfo.DirectoryName + "\\New\\" + fileNameRef;

            doc.SaveAs(ref saveFileName, ref missing, ref missing, ref missing, ref missing
                , ref missing, ref missing, ref missing, ref missing, ref missing, ref missing
                , ref missing, ref missing, ref missing, ref missing, ref missing);

        }
        catch (Exception)
        {
        }
        finally
        {
            doc.Close(ref missing, ref missing, ref missing);
            word.Application.Quit(ref missing, ref missing, ref missing);
        }

        return fileNameRef;
    }

Thanks for any help! And I do mean any, simply getting started on how to spot formatting would help a great deal, I imagine. :)

Upvotes: 0

Views: 4023

Answers (1)

Zev Spitz
Zev Spitz

Reputation: 15317

This is not a C#-specific question; it's a Word Object Model question (I refer you to here and here).

As to your specific question, I suggest you turn on the Macro Recorder in Word, perform the actions, and see the generated VBA code. Then you can apply it in C#.

Try this:

using System;
using Microsoft.Office.Interop.Word;
using System.IO;
using System.Reflection;

namespace WordFormattingFindReplace {
    class Program {
        static void Main(string[] args) {
        }

        public static string searchDoc(string fileName) {
            _Application word = new Application(); ;
            _Document doc;

            string folderName = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
            string filePath = Path.Combine(folderName,fileName);

            doc = word.Documents.Open(filePath);

            var find=doc.Range().Find;
            find.Text="Hello";
            find.Format=true;
            find.Replacement.Font.Name="Tahoma";
            find.Replacement.Font.ColorIndex=WdColorIndex.wdRed;
            find.Execute(Replace:WdReplace.wdReplaceAll);

            doc.SaveAs2(Path.Combine(folderName,"New",fileName));

            doc.Close();

            //We need to cast this to _Application to resolve which Quit method is being called
            ((_Application)word.Application).Quit();

            return fileName;
        }
    }
}

Some notes:

  • Use using statements for clarity. Instead of Microsoft.Office.Interop.Word._Application word, add using Microsoft.Office.Interop.Word at the top of your file, and you can then just write _Application word
  • If all you need is the folder name, use the static Path.GetDirectoryName method and save as a string variable, instead of creating a FileInfo object
  • As of .NET 4, you can skip optional arguments when calling Documents.Open, Document.SaveAs and Document.Close. This also means you don't need an object missing.
  • There's nothing here the user really needs to see, so calling Document.Activate is unnecessary
  • It's probably better to reuse the Word.Application instance, instead of recreating it for each call.

Upvotes: 1

Related Questions