65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 Visual Studio .NET 自动化 MS Word

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.56/5 (37投票s)

2003年12月19日

6分钟阅读

viewsIcon

477946

downloadIcon

6373

此代码将演示如何自动化和获取 MS Word 文档中的内容

引言

有一天,您可能会被要求编写一个解析器,该解析器需要解析大量文档,将它们分解为结构化模型,然后将它们存储在关系数据库中。而这些文档最有可能用 MS Word 编写。更糟糕的是,它们可能没有任何结构,不遵循任何标准,并且包含 OLE/嵌入式对象。我被分配了这样一项任务,这对我来说是一次非常有趣的经历。

由于这是我第一个此类项目,即自动化 MS Office 应用程序,所以我不得不去阅读大量关于自动化的资料。好消息是,有很多资料可供参考;坏消息是,所有这些资料都是为 VB 或 VBA 开发人员编写的。我找不到任何适合 C++ 开发人员的内容。长话短说,我写这篇文章是为了让那些可能被分配类似任务的人更容易一些。

我最初工作的代码是使用 Borland C++ Builder 5 Professional 编写的。然而,本文是 C# 版本。顺便说一句,如果您有兴趣看看 C++ 版本,可以提出来,我会发布。我鼓励大家有时间看一下 C++ 版本,开始欣赏 C# 的简洁性。

背景

不需要任何特殊背景。只需要有一些 C# 的实践经验。

使用代码

我将包含一些代码,让您了解如何从 Word 文档中获取所需内容。这实际上与您是创建控制台应用程序还是 Windows 应用程序无关。步骤和代码是相同的。所以您可以继续创建一个新的 C# 项目。您可以选择创建一个 Windows 应用程序,这样您就可以点击某个按钮。

好的,一旦您创建了一个新项目,请右键单击“解决方案资源管理器”中的“引用”,然后选择“添加引用…”。当“添加引用”窗口出现时,选择“COM”选项卡。这将列出您机器上可用的所有组件名称,因为我们将使用 MS Word,所以我们将向下滚动直到找到:Microsoft Word 9.0 对象库

注意:根据您机器上安装的 Office 版本,您的版本可能不同。这是针对 MS Word 2000 的。

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;

namespace sparser
{
  /// Summary description for Form1.
  public class frmParserMainUI : System.Windows.Forms.Form
  {
    /// User Interface Objects
    /// I have removed the user interface object, since 
    /// they have nothing to do with
    /// the actual code, and they take a lot of space.

    ...
    
    /// Required designer variable.
    private System.ComponentModel.Container components = null;
    private System.Windows.Forms.OpenFileDialog openFileDialog;
    
    ...

下面的代码块创建了 MS Word COM 对象。这个对象将用于访问 WORD 应用程序函数。要查看有哪些函数可用,您可以在 Visual Studio .NET IDE 或 MS Word 中进行。

    /// MS Word COM Object
    /// This is where we create our WORD object
    private Word.ApplicationClass vk_word_app = new Word.ApplicationClass();
    
    ...

要从 MS Word 查看函数,请启动 Word,按住 Alt 键并按 F11 [Alt+F11],这将打开 VBA 窗口,进入后按 F1 打开帮助窗口,然后搜索“document object”。这是可用的函数文档的最佳来源。然而,文档是为 VBA 编写的,但至少您知道函数的作用以及它接受什么类型的参数。

好了,代码继续...

    ...


    /// The main entry point for the application.
    [STAThread]
    static void Main() 
    {
      Application.Run(new frmParserMainUI());
    }

    /// Get source document. Open a FileDialog window for 
    /// user to select single/multiple files for
    /// parsing.
    private void butSourceDocument_Click(object sender, System.EventArgs e)
    {
      if( openFileDialog.ShowDialog() == DialogResult.OK )
      {
        object  fileName = openFileDialog.FileName;
        object  saveFile = fileName + "_Vk.doc";
        
        
        object  vk_read_only  = false;
        object  vk_visible  = true;
        object  vk_false    = false;
        object  vk_true    = true;
        object  vk_dynamic  = 2;
        
        object  vk_missing  = System.Reflection.Missing.Value;

        // Let make the word application visible
        vk_word_app.Visible = true;
        vk_word_app.Activate();

        // Let's open the document
        Word.Document vk_my_doc = vk_word_app.Documents.Open( 
          ref fileName, ref vk_missing, ref vk_read_only, 
              ref vk_missing, ref vk_missing,
          ref vk_missing, ref vk_missing, ref vk_missing, ref vk_missing,
          ref vk_missing, ref vk_missing, ref vk_visible );
               
               ...

好了,现在用户会看到一个文件打开对话框,他们可以在其中选择一个 Word 文档。请注意,我们将文件名保存为一个对象。这是因为我们使用的函数需要对象的引用。

因此,我们现在可以使用我们的 Word 对象来启动 Word。这通过 vk_word_app.Visible = true;vk_word_app.Activate(); 来实现。第一个语句确保 Word 实例可见,第二个语句激活它。如果您不希望 Word 实例可见,只需将 Visible 属性设置为 false

接下来,我们创建一个 Word 文档对象,使用 Word.Document vk_my_doc = vk_word_app.Documents.Open( ... ); 来完成。请注意该函数所需的所有参数。其中大多数是 NULL 值,所以我们使用 vk_missing,它是 System.Reflection.Missing.Value

现在我们已经创建了一个 Word 实例并打开了一个 Word 文档。现在让我们继续编写代码...

    ...

        // Let's create a new document
        Word.Document vk_new_doc = vk_word_app.Documents.Add( 
        ref vk_missing, ref vk_missing, ref vk_missing, ref vk_visible );

        // Select and Copy from the original document
        vk_my_doc.Select();
        vk_word_app.Selection.Copy();

        // Paste into new document as unformatted text
        vk_new_doc.Select();
        vk_word_app.Selection.PasteSpecial( ref vk_missing, ref vk_false,
          ref vk_missing, ref vk_false, ref vk_dynamic, 
          ref vk_missing, ref vk_missing );

        // close the original document
        vk_my_doc.Close( ref vk_false, ref vk_missing, ref vk_missing );
    ...

接下来,我们想创建一个新文档。这就像点击工具栏上的“新建空白文档”按钮一样。所以我们创建另一个 Word 文档对象,这次请注意我们使用 vk_word_app.Documents.Add( ... );。这将添加一个新的空白文档,它也是可见的。

接下来,我们选择打开的文档中的所有内容,然后复制它。

接下来,我们以特殊格式将内容粘贴到新文档中。代码中使用的格式是纯文本。这是因为我们想去除 Word 插入的格式垃圾。然后,我们关闭原始文档而不进行任何更改。

    ...

        vk_new_doc.Select();
        FindAndReplace( "^t^t^t^t^t^t^t", "^t", vk_num );

        // Save the new document
        vk_new_doc.SaveAs( ref saveFile, ref vk_missing, 
          ref vk_missing, ref vk_missing, ref vk_missing,
          ref vk_missing, ref vk_missing, ref vk_missing, 
          ref vk_missing, ref vk_missing, ref vk_missing );

        // close the new document
        vk_new_doc.Close( ref vk_false, ref vk_missing, ref vk_missing );

        // close word application
        vk_word_app.Quit( ref vk_false, ref vk_missing, ref vk_missing );
      }
    }

    ...

现在,假设我们想进行查找和替换操作,我们基本上会选择整个文档并使用“查找和替换”功能。

注意:FindAndReplace 函数不属于 Word 对象或 Document 对象,它是用户定义的,实际的查找和替换函数定义在下面的代码块中。

接下来,我们想将更改保存到新文档并关闭它。

最后,退出 Word。

    ...

    private void FindAndReplace( object vk_find, object vk_replace, 
       object vk_num )
    {
      object  vk_read_only  = false;
      object  vk_visible    = true;
      object  vk_false      = false;
      object  vk_true      = true;
      object  vk_dynamic    = 2;

      vk_word_app.Selection.Find.Execute( ref vk_find, 
        ref vk_false, ref vk_false,
        ref vk_false, ref vk_false, ref vk_false, ref vk_true, 
        ref vk_num, ref vk_false,
        ref vk_replace, ref vk_dynamic, ref vk_false, 
        ref vk_false, ref vk_false, ref vk_false );
    }
  }
}

上面的代码块显示了实际的 FindAndReplace 函数。请注意,它属于 vk_word_app 对象。该函数作用于活动选择。查找和替换函数是 Find 函数的一部分,具有特殊参数。这些参数可以在我文章开头提到的文档中找到。

上面演示的代码说明了如何打开一个 Word 文档,如何创建一个新的 Word 文档,如何选择、复制、粘贴以及执行查找和替换功能。

如您所见,一旦您理解了 Word 的工作方式并通过文档,您就可以自动化 Word 提供的所有功能。

        // Let's get the content from the document
        Word.Paragraphs vk_my_doc_p = vk_new_doc.Paragraphs;
        // Count number of paragraphs in the file
        long p_count = vk_my_doc_p.Count;
        // step through the paragraphs
        for( int i=1; i<=p_count; i++ )
        {
          Word.Paragraph vk_p = vk_my_doc_p.Item( i );
          Word.Range vk_r = vk_p.Range;
          string text = vk_r.Text;

          MessageBox.Show( text );
        }

如果您看一下上面的代码,您可以看到我们声明了一个对象,该对象表示 Word 文档中的一个段落。这就是您可以从 Word 文档中提取文本的方式,您获取段落对象,然后可以访问列表中包含的所有段落。代码遍历给定文档的每个段落,并在 MessageBox 中显示它们。

关注点

新版本的 Office,Office 2003 将使 Office 开发人员的工作更加轻松。所以,如果您是一名 Office 开发人员,您应该开始关注 Office 2003 提供的功能。我喜欢的一个很棒的功能是将文档导出为 XML 格式的功能。

© . All rights reserved.