Search code examples
c#datatablecomms-wordms-office

How to insert table into Word document in place of text mark?


I have DateTable. Need to insert it instead of some set of characters in teplate document.

I can replace text-to-text this way (lots of missingObj to avoid the bugs):

    using Word = Microsoft.Office.Interop.Word;

    Word._Application application;
    Word._Document document;
    Object missingObj = System.Reflection.Missing.Value;
    Object trueObj = true;
    Object falseObj = false;

    private void create_button1_Click(object sender, EventArgs e) {
            application = new Word.Application();
            Object templatePathObj;
            templatePathObj = "template.dot";  

            try {
                document = application.Documents.Add(ref  templatePathObj, 
                    ref missingObj, ref missingObj, ref missingObj);
            }
            catch (Exception error) {
                document.Close(ref falseObj, ref  missingObj, ref missingObj);
                application.Quit(ref missingObj, ref  missingObj, ref missingObj);
                document = null;
                application = null;
                throw error;
            }

            object strToFindObj = "%%mark%%";
            object replaceStrObj = "text to replace";
            Word.Range wordRange;
            object replaceTypeObj;
            replaceTypeObj = Word.WdReplace.wdReplaceAll;
            for (int i = 1; i <= document.Sections.Count; i++) {
                wordRange = document.Sections[i].Range;
                Word.Find wordFindObj = wordRange.Find;
                object[] wordFindParameters = new object[15] { strToFindObj, missingObj, 
                    missingObj, missingObj, missingObj, missingObj, missingObj, missingObj, 
                    missingObj, replaceStrObj, replaceTypeObj, missingObj, missingObj, 
                    missingObj, missingObj };
                wordFindObj.GetType().InvokeMember("Execute", BindingFlags.InvokeMethod, 
                    null, wordFindObj, wordFindParameters);
        }
        application.Visible = true;
    }

What i have to change so this code will take DataTable instead of strToFindObj?

In this example i replace stuff in Range, what is some fragmen of document including tables, format, etc.


Solution

  • lots of missingObj to avoid the bugs

    Target .Net 4.0 or above supports named and optional arguments with COM calls so you wont need to include all the ref missingObj. See this MSDN Article: Named and Optional Arguments - This capability greatly facilitates calls to COM interfaces such as the Microsoft Office Automation APIs.


    What do I have to change so I can search using a DataTable instead of string variable strToFindObj?

    You would have to iterate through the DataTables Row's and Cell's replacing the DataTable cells in the Word Document, eg:

    foreach(var dr in dt.Rows)
    {
      foreach (var cell in dr.ItemArray)
      {
        string strToFind = cell.ToString();
        string replaceStr = "replace old value";
        ReplaceTextInWord(@"C:\Temp\template.docx", strToFind, replaceStr);
      }
    }
    

    If you find using a DataTable too hard and want a list (like a Dictionary) that's even easier:

    var listOfTextToReplace = new Dictionary<string,string>();
    listOfTextToReplace.Add("%%mark%%","text to replace");
    foreach(var item in listOfTextToReplace )
    {
        string strToFind = item.Key;
        string replaceStr = item.Value;
        ReplaceTextInWord(@"C:\Temp\template.docx", strToFind, replaceStr);
    }
    

    Here is the ReplaceTextInWord method:

    using Word = Microsoft.Office.Interop.Word;
    Word._Application application;
    Word._Document document;
    Object missingObj = System.Reflection.Missing.Value;
    Object trueObj = true;
    Object falseObj = false;
    
    private void create_button1_Click(object sender, EventArgs e) {
       //ReplaceTextInWord("template.dot", "find me", "Found"); <-- Are you sure you want to replace in a Template?
       ReplaceTextInWord(@"C:\Temp\template.docx", "%%mark%%","text to replace");  //I think you want a .DOC or DOCX file
    }
    
    private void ReplaceTextInWord(string wordDocFilePath, string strToFind, string replaceStr) {
        application = new Word.Application();
        try {
            //document = application.Documents.Add(ref templatePathObj, ref missingObj, ref missingObj, ref missingObj); 
            document = application.Documents.Open(wordDocFilePath);  //You need to open Word Documents, not add them, as per https://msdn.microsoft.com/en-us/library/tcyt0y1f.aspx
        }
        catch (Exception error) {
            document.Close(ref falseObj, ref missingObj, ref missingObj);
            application.Quit(ref missingObj, ref missingObj, ref missingObj);
            document = null;
            application = null;
            throw error;
        }
    
        for (int i = 1; i <= document.Sections.Count; i++) {
        Word.Range wordRange = document.Sections[i].Range;
        Word.Find findObject = wordRange.Find;
        findObject.ClearFormatting();
        findObject.Text = strToFind;
        findObject.Replacement.ClearFormatting();
        findObject.Replacement.Text = replaceStr;
    
        object replaceAll = Word.WdReplace.wdReplaceAll;
        findObject.Execute(ref missing, ref missing, ref missing, ref missing, ref missing,
            ref missing, ref missing, ref missing, ref missing, ref missing,
            ref replaceAll, ref missing, ref missing, ref missing, ref missing);
        }
        application.Visible = true;
    }
    

    Ref MSDN: How to: Programmatically Search for and Replace Text in Documents