原文地址以及相关代码
想着回家过年,没有仔细检查,如果有纰漏,请指出!
用Visual Studio .NET自动化MS Word
介绍
有一天,你也许被要求写一个解析器,它将必须能解析一批文档,然后把它们分解成一个结构化的模型并把它们存储在一个关系数据库中。还有那些文档将很可能就是用MS Word所编辑的,最惨的就是它们没有任何结构,也不遵循任何标准,还可能包含一些OLE/嵌入式对象。我就被分派了个这样的任务,它对我来说是一个非常有意思的体验。
由于这是我的第一个这样的项目,就是意味着将自动化MS Office应用程序,我不得不去做大量的关于自动化方面的阅读,好消息就是有许多相关的资料,坏消息就是所有那些都是由VB或VBA开发人员写的,我找不到任何由C++程序员写的东西。好了,长话短说,我正写的这篇文章将会使得被分派了相似任务的开发人员的事情就简单点了。.
原始代码我是使用Borland C++ Builder 5专业版开发的。然而,在这篇文章中是C#版本。顺便说一句如果你有兴趣看下C++版本的话,就找我要,我会电邮给你。我鼓励大家在开始欣赏C#版本的简便之前,找个时间看看C++版本。
背景
没有什么特殊背景是必需的。仅仅有一些使用C#的经验。
使用的代码Using the code
我将在文章中包含一些代码,这将有助你理解怎么样从一个Word文档中得到你想要的东西,是否你是建的是一个控制台程序,还是Windows程序,这都没有什么关系,步骤和代码都是相同的,因此你能向前走,建立一个C#工程。你可以选择一个Windows程序,这样你就能有按钮可用按了。
好了,你一旦建立一个新工程,继续前进,右键单击在“解决方案浏览器”中“引用”,然后选择“添加引用”……,当“添加引用”窗口出现时,选择“COM”标签。这将显示你机器中所有可用组件的名称,既然我们将用到MS Word,我们将一直向下移动滚动条直到找到:Microsoft Word 9.0 Object Library。
注意:Note: 你的也许是不同版本,这将依赖于你安装在你机器中的Office的版本,这儿是的MS Word 2000。
using System;下面的模块创建一个MS Word COM 对象,这个对象将被用来访问WORD应用程序的函数。为了明白什么函数是可用的,你能够在Visual Studio .NET IDE 或 MS Word中做到这。
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;
1 /// MS Word COM Object为了从MS Word中查看功能,启动Word,按下Alt和F11[Alt+F11],这将显示给你一个VBA窗口,一旦按下F1你就可用打开了帮助窗口,对文档对象进行搜索,对那些可用的函数来说这是最好的文档资源。然而,这些都是为了VBA开发写的,但是我们至少知道函数是做什么的,它携带什么类型的参数。
2 /// This is where we create our WORD object
3 private Word.ApplicationClass vk_word_app = new Word.ApplicationClass();
4
5
6
好的,代码继续……
2
3
4 /// The main entry point for the application.
5 [STAThread]
6 static void Main()
7 {
8 Application.Run(new frmParserMainUI());
9 }
10
11 /// Get source document. Open a FileDialog window for
12 /// user to select single/multiple files for
13 /// parsing.
14 private void butSourceDocument_Click(object sender, System.EventArgs e)
15 {
16 if( openFileDialog.ShowDialog() == DialogResult.OK )
17 {
18 object fileName = openFileDialog.FileName;
19 object saveFile = fileName + "_Vk.doc";
20
21
22 object vk_read_only = false;
23 object vk_visible = true;
24 object vk_false = false;
25 object vk_true = true;
26 object vk_dynamic = 2;
27
28 object vk_missing = System.Reflection.Missing.Value;
29
30 // Let make the word application visible
31 vk_word_app.Visible = true;
32 vk_word_app.Activate();
33
34 // Let's open the document
35 Word.Document vk_my_doc = vk_word_app.Documents.Open(
36 ref fileName, ref vk_missing, ref vk_read_only,
37 ref vk_missing, ref vk_missing,
38 ref vk_missing, ref vk_missing, ref vk_missing, ref vk_missing,
39 ref vk_missing, ref vk_missing, ref vk_visible );
40
41
42
好的,因此在这会给用户一个打开文件的对话框,在这他们能选择一个要打开的Word文档,注意我们把文件名保存为一个对象,这是因为我们用到的函数需要引用对象。
那么现在我们能用Word对象启动Word,这是由vk_word_app.Visible =
true;和
vk_word_app.Activate();
两个语句来完成的。第一个语句保证Word实例是可见的,第二个语句就是激活它,如果你不想让Word实例是可见的,你仅需要把 Visible
属性设为false。
接下来,我们创建一个Word Document对象,这是用语句Word.Document vk_my_doc = vk_word_app.Documents.Open( ... );
来完成的,注意所有该函数需要的参数,大多是NULL
值,所以我们用use vk_missing
这是一个System.Reflection.Missing.Value
.
那么现在我们创建了一个Word实例,并打开了一个Word文档,现在我们继续前进……
2
3 // Let's create a new document
4 Word.Document vk_new_doc = vk_word_app.Documents.Add(
5 ref vk_missing, ref vk_missing, ref vk_missing, ref vk_visible );
6
7 // Select and Copy from the original document
8 vk_my_doc.Select();
9 vk_word_app.Selection.Copy();
10
11 // Paste into new document as unformatted text
12 vk_new_doc.Select();
13 vk_word_app.Selection.PasteSpecial( ref vk_missing, ref vk_false,
14 ref vk_missing, ref vk_false, ref vk_dynamic,
15 ref vk_missing, ref vk_missing );
16
17 // close the original document
18 vk_my_doc.Close( ref vk_false, ref vk_missing, ref vk_missing );
19
20
接下来我们将创建一个新文档,这就想我们在工具栏点击下“新空白文档”按钮一样,因此我们创建另一个Word Document对象,注意这次我们用到vk_word_app.Documents.Add( ... );
语句,这将添加一个新的空白文档,它也是可见的。
接下来,我们选择那被打开的文档的全部内容,并复制它。
接下来,我们把内容用一种特殊的格式粘贴在那新文档中,代码中用的是针对纯文本的格式,这是因为我们想去除废弃文档注入文本的格式,然后我们关闭原始文档不做任何更改。
1现在让我们说下,如果我们对查找(find)和替换(replace)操作感兴趣,基本上是我们将选择整个文档使用Find和Replace函数。.
2
3 vk_new_doc.Select();
4 FindAndReplace( "^t^t^t^t^t^t^t", "^t", vk_num );
5
6 // Save the new document
7 vk_new_doc.SaveAs( ref saveFile, ref vk_missing,
8 ref vk_missing, ref vk_missing, ref vk_missing,
9 ref vk_missing, ref vk_missing, ref vk_missing,
10 ref vk_missing, ref vk_missing, ref vk_missing );
11
12 // close the new document
13 vk_new_doc.Close( ref vk_false, ref vk_missing, ref vk_missing );
14
15 // close word application
16 vk_word_app.Quit( ref vk_false, ref vk_missing, ref vk_missing );
17 }
18 }
19
20
21
注意:Note: 这个 FindAndReplace
函数不属于Word
对象 或者 Document
对象,它是用户定义的,实际上Find和Replace函数定义在下面的模块中。
接下来我们想更改我们的新文档并且关闭它。
最后退出word.
1上面模块展示了实际的
2
3 private void FindAndReplace( object vk_find, object vk_replace,
4 object vk_num )
5 {
6 object vk_read_only = false;
7 object vk_visible = true;
8 object vk_false = false;
9 object vk_true = true;
10 object vk_dynamic = 2;
11
12 vk_word_app.Selection.Find.Execute( ref vk_find,
13 ref vk_false, ref vk_false,
14 ref vk_false, ref vk_false, ref vk_false, ref vk_true,
15 ref vk_num, ref vk_false,
16 ref vk_replace, ref vk_dynamic, ref vk_false,
17 ref vk_false, ref vk_false, ref vk_false );
18 }
19 }
20}
21FindAndReplace
函数。注意,它属于vk_word_app
对象,还有这个函数处理活动的选择,Find和Replace函数是Find函数的一部分,使用特殊的参数。这些参数在文件中被识别,就如在本文的前面我提到的那样。
上面的代码演示,例证怎样打开一个word文档、怎样创建一个新文档,选择、复制、粘贴以及进行查找和替换功能。
就像我们能看到那样,一旦你理解Word如何操作还有检查文件,你也将能够自动化所有Word提供的功能。
1 // Let's get the content from the document如果你看一下上面的代码,你能看到我们申明了一个对象,它表示了Word文档中的段落,这就是你怎么能从一个Word文档中析取文本,你有了这段落对象就能访问列表中所有段落。这段代码循环给定文档中的每个段落并它们显示在
2 Word.Paragraphs vk_my_doc_p = vk_new_doc.Paragraphs;
3 // Count number of paragraphs in the file
4 long p_count = vk_my_doc_p.Count;
5 // step through the paragraphs
6 for( int i=1; i<=p_count; i++ )
7 {
8 Word.Paragraph vk_p = vk_my_doc_p.Item( i );
9 Word.Range vk_r = vk_p.Range;
10 string text = vk_r.Text;
11
12 MessageBox.Show( text );
13 }
14MessageBox
中。