使用.Net访问Office编程接口

Office with .Net (二) ――― 使用.Net访问Office编程接口
 
在这篇文章里面,我将向大家介绍如何在.Net中访问Office所公开的编程接口。其实,不管是使用哪种具体的技术来针对Office进行开发(比如VSTO,或者用C#编写一个Office Add-in,或者在一个WinForms程序中调用Office的功能,甚至在一个ASP.NET应用的服务器 Excel进程),只要是基于.Net平台,这篇文章所描述的内容都是有价值的。
 
在这篇文章以及后续的文章中,所有的演示都将基于Office 2003 Professional和Visual Studio 2005。使用Visual Studio 2005并不代表我们不能在Visual Studio 2003中使用这些方法来访问Office编程接口,相反,这篇文章以及后续文章中的几乎所有演示,都能在Visual Studio 2003中完成。笔者使用Visual Studio 2005的原因只是因为喜欢它更好的IDE特性。:)
 
一、Office PIA
 
在第一篇文章中曾经说过,Office的编程接口都是通过COM组件公开的,任何访问Office编程接口的程序,实际上都必须要最终调用Office COM组件。如果你是一个刚从事Windows平台开发不太久,一开始就是学习和使用.Net的程序员,也许你又要感到郁闷了。所幸的是,.Net能够让开 COM组件。我会用尽量简洁明了的描述,让大家理解我们在.Net中是如何访问Office COM组件的。
 
(一)Interop Assembly
 
在.Net Framework中,提供了一项叫做COM Interop的技术,这项技术就是专门用于让我们能够在.Net代码中直 COM组件的。它的基本原理是,.Net Framework能够自动针对某一个COM组件,帮助开发人员生成一个Interop Assembly(互调用程序集,后面简称IA),IA是一个完全的托管程序集。IA中的名称空间、类、方法等等,都是针对那个COM组件对应的。在我们的.Net程序中,我们可以直接引用这个IA,并且调用里面相关的方法,这时IA就会帮我们再去访问真正的COM组件里面的相应方法。最后的效果就是,在我们自己的应用程序中,只需要调用一个纯粹.Net的IA即可。
 
下面的图片说明了IA是如何帮我们的程序访问到COM组件的。
 
生成一个IA的方法非常简单,当我们在Visual Studio开发环境中添加一个新的COM组件引用时,Visual Studio就会自动帮我们生成一个相应的IA。如下图,我们示范在一个项目中引用Microsoft XML 5.0组件。
 
当在上图中点击OK按钮,Visual Studio就已经自动为我们生成了一个针对Microsoft XML 5.0组件的IA。打开项目目录的obj/debug目录,就能够看到一个名称为Interop.MSXML2.dll的程序集文件,这个文件就是自动生成的IA,并且在项目中,Visual Studio也自动引用了这个IA程序集。如下图。
 
(二)Primary Interop Assembly
 
我们在自己的应用程序中,访问Office COM组件的方法的基本原理,就如同下面所述,都是通过COM Interop,透过IA间接的访问到Office中的COM组件。但是针对Office这个软件,则有一点点特殊的区别,那就是我们不应该自己在Visual Studio中生成一个“自己的”访问Office COM的IA,而需要使用微软提供的“官方的”PIA。
 
PIA的意思可以理解为“官方互操作程序集”,它和IA最主要的区别如下:
1、IA是由开发人员在开发机器上通过向导自动生成的,PIA是由软件厂商(针对Office这个软件而言,就是指微软)提供的;
2、PIA经过了厂商的优化处理,使之更容易被.Net调用;
 
(三)Office Primary Interop Assembly
 
所以,我们都应该使用PIA来访问Office COM组件,而不应该使用IA。那么如何把Office PIA安装到我们的电脑上呢?
 
如果我们的机器上已经安装了.Net Framework,那么在安装Office时,在安装向导的高级自定义选项中,我们在每个组件(Word、Excel、PowperPoint等)的子选项中,都能看到一个“.NET可编程性支持”,选择安装它,Office2003的安装程序就会自动把PIA安装到我们的计算机上。
 
另外,对于Office PIA的客户端分发(就是说,给我们软件的用户都统一装上PIA),微软专门提供了一个安装包。可以在 http://www.microsoft.com/downloads/details.aspx?FamilyID=3c9a983a-ac14-4125-8ba0-d36d67e0f4ad&DisplayLang=en下载到这个分发安装包。
 
Office PIA按照Office的各个组件(Word、Excel、PowerPoint、Outlook等),分成多个单独的程序集。比如Word对应的PIA程序集是Microsoft.Office.Interop.Word.dll(程序集里面 Microsoft.Office.Interop.Word中),Excel对应的程序集是Microsoft.Office.Interop.Excel.dll(程序集里面Microsoft.Office.Interop.Excel中)。另外,Office公用的一些组件(比如菜单栏)放在一个单独的程序集中:Office.dll(对应的命名空间是Microsoft.Office.Interop.Core)。
 
如果我们的开发机器上已经安装好了Office PIA,那么当我们通过上面所述的方法,在Visual Studio中引用Office COM组件时,Visual Studio会检测到本机已经安装了Office PIA,然后,它会直接引用安装好了的PIA,而不会再自动生成一个新的IA。
 
如下图,我们在Visual Studio中添加一个对Word COM组件的引用(Word在COM组件列表中是“Microsoft Word 11.0 Object Library”,相似的,Excel、Outlook、PowerPoint的COM组件名称都遵循这个规律)。
 
在上图中点击OK按钮后,在项目管理器中就可以看到,Visual Studio已经帮我们引用了需要引用的组件。实际上,除了我们选择要引用的Word组件外,其他 Microsoft.Office.Core、stdole、VBIDE等组件也已经被自动引用进来了。
 
在上图的Word组件引用上点击鼠标右键,查看它的属性,在它的路径属性中,我们可以看到这个PIA文件其实是在“C:/Windows/assembly/...”目录中,这个目录也就是我们机器上的全局程序集缓存(GAC,Global Assembly Cache)所在的目录。这是因为Office PIA是被安装到机器上的GAC中,所以对Office PIA的引用会直接指向GAC中的相应文件。
 
二、深入浏览Office PIA
 
如果读者曾经使用过VBA进行过开发(或者使用其他的开发工具诸如VB/VC/Delphi直接调用过Office),那么其实你已经对Office COM接口有了一定的了解,因为在VBA编辑器中所编写的操作诸如Application、Document、Range的代码,其实正是在操作Office COM组件中的Application、Document、Range这些类。
 
我们已经知道,在Office PIA中,已经把Office COM组件进行了封装,所以我们可以预见,对于每一个Office COM组件中的 Office PIA的程序集中,我们应该都能找到一个对应的Office COM组件,然后再打开Office PIA,这样我们就可以对照它们,更清楚的理解它们。
 
在Visual Studio中,打开视图菜单中的对象浏览器,然后点击对象浏览器中的添加其他组件按钮,在出现的选择窗口中,选择COM组件中的“Microsoft Word 11 Object Library”,这时对象浏览器就直接打开了Word 2003的COM组件,如下图。
 
在上图所示的Word COM组件成员列表中,可以看到我选中了Word中的Application类的Quit()方法。Application类可以说是各个Office组件的核心类,不管是Word、Excel、PowerPoint,都存在一个对应的Application类,对应Word、Excel、PowerPoint主程序。如果要在我们的程序中直 Word,就需要创建这个Application类的一个实例,如果要关闭掉这个新打开的Word程序,就调用这个新创建的Application对象的Quit()方法。
 
接下来,我们再用对象浏览器打开Office PIA中的Word所对应的程序集。在前面的操作步骤中,我们已经在项目中引用了Word的PIA,在项目管理器的引用列表中选中Word,点击鼠标右键,选择在对象浏览器中查看,就可以在对象浏览器中打开Word的PIA了。如下图。
 
如果在上图所示的Microsoft.Office.Interop.Word命名空间所包含的类中做一些浏览,相信读者会发现一个很有意思的事情。那就是其实Word的PIA中的类、接口,并不是和Word的COM组件中的类、接口一一对应的。比如,我们在Word COM组件中能够看到一个叫做Application的类,但是在Word的PIA中,我们只能找到一个叫做Application的接口,和一个叫做ApplicationClass的类。
 
出现这个情况的原因,在于.Net的COM Interop(具体说就是.Net SDK中的TlbImp.exe这个命令行工具)帮我们根据COM组件生成Interop Assembly时,其实是不会一一对照COM组件来生成.Net类和接口的。相反,它会根据一定的规则,来生成对应的.Net类和接口。
 
由于Application是Word编程接口中最重要的部分,所以我具体针对Word中的Application这个接口,把它的转换规则简要的说明一下(实际生成的接口和类比下面描述的要更多,相关的关系更复杂)。首先,Word PIA中会生成一个_Application接口,这个_Application接口基本描述了Word COM组件中的Application类中的所有操作和属性,然后,Word PIA中还会生成多个ApplicationEvents_Event系列接口(ApplicationEvents2_Event、ApplicationEvents3_Event、ApplicationEvents4_Event接口…我们可以不用管这些具体的细节),这个接口基本描述了Word COM组件中的Application类中的所有事件。然后,Word PIA中会生成一个Applicatin接口,它实现了_Application接口和ApplicationEvents_Even接口,这样,Application接口就基本描述了Word COM组件中的Application类中的所有操作、属性、事件等等。最后,Word PIA中生成了一个具体的ApplicationClass类,这个 Applicatin接口。
 
如果你已经被上面那一段描述搞得头昏脑胀,那么只需要记住:在Word PIA中,我们有一个Application接口和一个ApplicationClass类,Application接口描述了对应的Word COM组件中的Application类的所有成员,而ApplicationClass类是具体的实现类。
 
三、Code WalkThrough:一个.Net WinForms程序
 
终于,在你忍受了N久, C#写一个Windows应用程序,在这个程序中,启动Word,用代码操作它做一些操作,然后再关闭掉它。
 
首先,我们创建一个新的C# Windows应用程序,然后通过上面介绍过的方法,在项目中引用Word的PIA(在添加引用的界面中,选择COM组件列表中的Microsoft Word 11 Object Library)。
 
在自动创建的启动窗体上,放两个Button控件,一个叫做btnStartWord,另外一个叫做btnStopWord。我们希望当用户点击btnStartWord时,我们的程序自动启动Word,然后创建一个新的Word文档,然后将其自动保存在磁盘上,当用户点击btnStopWord时,就关闭掉Word。窗体设计视图如下。
 
 
在这个主窗体类的源代码中,我们引用Word PIA的名称空间,我们使用MSWord来替代Microsoft.Office.Interop.Word这个完整的命名空间名称:
 

using MSWord = Microsoft.Office.Interop.Word;

 
在主窗体类的源码中,添加一个类级别的成员,_wordApp是一个Application类型的对象(记住:MSWord.Application是一个接口!):
 

private MSWord.Application _wordApp = null;

 
然后在btnStartWord按钮的点击事件代码中,添加如下代码,代码创建一个新的Word实例,然后显示它:
 

_wordApp = new

_wordApp.Visible = true;
 
看到这里,很多人有一个非常大的疑惑,那就是MSWord.Application实际上是一个接口,那么我们怎么可能通过“new MSWord.Application()”来创建一个Word实例呢?难道我们不应该使用“new MSWord.ApplicationClass()”来做吗?毕竟ApplicationClass才是实现Application接口的具体类啊。
 
在这里,Office PIA为我们提供了一个小小的“cookie”,我们实际上的确可以使用“new MSWord.Application()”来创建一个Word程序实例的,我们只需要知道,Office PIA会在底下自动帮我们创建一个真正的Word程序实例。
 
接下来,我们在btnStartWord按钮的事件代码中,再添加如下的代码。
 
Object missing = Type.Missing;
Object sFileName = "C://Sample.doc";
 
MSWord.Documents docs = _wordApp.Documents;

MSWord.Document doc =

doc.SaveAs(ref sFileName, 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.Close(ref missing, ref missing, ref missing);

 
在上面的代码中,我们通过访问Application的Documents属性,得到一个Documents类,然后通过Documents类的Add()方法,创建一个新文档,并得到对应这个新文档的类型为Document的对象,然后通过Document类的SaveAs()方法将文档保存在磁盘上,最后通过Document类的Close()方法关闭这个新文档。
 
嗯,我知道我其实解释得不够彻底,上面代码中的那些ref、missing之类的东 VBA或其他语言访问过Office COM组件接口的程序员而言)。这其实牵涉到用C#语言调用Office编程接口的一个“语法兼容”问题。就是说,Office的产品开发组在对编程接口进行设计时,实际上是专门设计为被VBA调用的,所以接口都非常配合VBA的语法,使VBA程序员尽量感到方便。但是由于C#语法和VB语法有很多不同,所以在用C#访问Office编程接口时,就会感到非常的“别扭”。
 
这这里,我只想对上面的代码做如下简要的额外解释:
(1)很多的Office编程接口中的方法,都带了非常多的参数(比如Document.SaveAs()方法有16个参数!!!),而实际上我们调用它们的时候,并不是每一个参数都需要明确给一个特定的值的(比如Document.SaveAs()方法只需要明确给定第一个参数,即保存到哪里),那么对于不需要给定明确值的参数,我们可以直接传一个.Net类库中自带的静态对象:Type.Missing就可以了。
(2)很多的Office编程接口中的方法,其参数都必需传引用,而不能传值,所以,调用这些方法的时候,对于参数都需要加上C#中的ref关键字。比如上面代码中的Document.Add()、Document.SaveAs()、Document.Close()方法,它们的参数都必须传引用,所以每个参数前面都加上了ref关键字。
 
对于使用C#语言调用Office编程接口时,对“语法兼容”问题的更全面的描述,请参看《Office with .Net(二)之外传―――C#访问Office编程接口时的“语法兼容”问题》。
 
继续为我们的项目添加代码。在btnStopWord按钮的事件代码中,填充下面的代码:
 
Object missing = Type.Missing;
 

_

 
_wordApp = null;
 

GC.Collect();

GC.WaitForPendingFinalizers();

GC.Collect();

GC.WaitForPendingFinalizers();

 
上面的代码通过调用Application.Quit()方法,退出Word程序。更值得关注的部分是如何释放掉Word程序实例。上面的代码用了一个简单但是很有效的方法,让Word程序进程被关闭回收,首先将对象_wordApp重新赋值为null,这样底下的那个Word Application对象将不再被任何变量引用,最后通过强行调用.Net Framework中的垃圾收集方法,使Application对象能够被垃圾 .Net Framework的垃圾Office PIA的一个包装类对象而已,但是这个包装类对象被回收后,对应Word程序的COM组件对象会发现自己不再被其他任何对象引用,引用计数变为了0,于是,那个COM组件就会被真正释放掉了。)
 
如何保证在自己的应用程序中关闭Office程序其实是一个不小的问题,上面描述的方法并不是100%有效的,对这个话题更完整的描述请参考《Office with .Net(二)之外传―――“彻底干净的”关闭Office程序》一文。
 
我们的第一个示范程序到这里就已经写完了,现在我们可以运行一下这个程序,然后先点击第一个按钮启动Word,并操作Word创建一个新文档后再保存到磁盘上,接着点击第二个按钮关闭掉Word。
 
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: VB.Net是一种基于.NET平台的编程语言,可以用来开发各种应用程序,包括与Microsoft Office进行交互的应用程序。VB.Net Office控件是一组用于操作和控制Microsoft Office软件(如Word、Excel、PowerPoint等)的工具集合。 VB.Net Office控件提供了丰富的功能和接口,使我们能够在应用程序中创建、打开、编辑和保存Office文档。它提供了简单而强大的对象模型,可以访问Office应用程序的各个组件(如文档、工作表、幻灯片等)以及它们的属性和方法。 使用VB.Net Office控件,我们可以编写代码来自动执行一系列操作,例如创建新的Word文档,将数据填充到Excel工作表中,从PowerPoint幻灯片中提取数据等等。我们可以通过编程方式控制Office应用程序的各个方面,如格式设置、数据导入导出、图表创建、自定义菜单等。 此外,VB.Net Office控件还提供了与Office应用程序进行交互的功能,例如打开和关闭Office应用程序、调用Office应用程序的功能和命令、处理Office应用程序的事件等。通过这些功能,我们可以根据具体需求来定制应用程序,以实现更高的自动化和扩展性。 总结来说,VB.Net Office控件是一种方便的工具,可以帮助我们在VB.Net应用程序中利用Microsoft Office软件的强大功能。它提供了丰富的功能和接口,使我们能够轻松地与Office应用程序进行交互,并能够编写代码来自动化执行各种操作。 ### 回答2: VB.NET是一种面向对象的编程语言,可以通过使用Office控件来操作Microsoft Office软件。Office控件库为开发人员提供了一组功能强大的工具,使其能够在自己的应用程序中嵌入和自动化Office应用程序。以下是VB.NET Office控件的一些主要功能和用途: 1.自动化Office应用程序:使用VB.NETOffice控件,可以自动化执行许多Office应用程序的操作,如创建和编辑Word文档、Excel表格和PowerPoint演示文稿。 2.读写Office文档:通过VB.NETOffice控件,可以轻松读取和修改Office文档中的内容,例如从Excel表格中读取数据、向Word文档中添加文本、创建幻灯片等。 3.与Outlook集成:使用VB.NETOffice控件,可以通过创建和发送电子邮件、管理日历和联系人,与Outlook进行集成。 4.自定义菜单和工具栏:通过VB.NETOffice控件,可以在Office应用程序中创建自定义菜单和工具栏,以实现特定的操作和功能。 5.数据分析和报告生成:使用VB.NETOffice控件,可以将数据导入到Excel中进行分析和报告生成,将数据展示为图表、图形和表格。 通过VB.NETOffice控件,开发人员可以轻松地利用Microsoft Office软件的功能,实现自定义的业务需求。无论是自动化处理大量文件、与Outlook进行交互还是生成专业的报告,VB.NETOffice控件都是非常有用的开发工具。 ### 回答3: VB.NET是一种流行的编程语言,用于开发Windows平台上的应用程序。Office控件是VB.NET中的一组特殊控件,用于与Microsoft Office套件中的各种应用程序进行交互和集成。 VB.NET中的Office控件包括Word控件、Excel控件和PowerPoint控件等,它们都是通过与Office应用程序的COM接口进行通信来实现功能的。 使用VB.NET中的Office控件,我们可以通过编程方式创建、打开、编辑和保存Word文档、Excel电子表格和PowerPoint演示文稿。我们可以使用这些控件来实现自定义的表格、图表和图形,以及添加、修改和删除文本、图像和媒体内容。 除了处理文档内容,Office控件还提供了与文档格式和样式相关的功能。我们可以通过控件修改字体、颜色、对齐方式等文本格式,并可以应用预定义的样式和主题。 此外,Office控件还允许我们执行一些高级操作,比如使用一组预定义的功能和方法来进行邮件合并、数据筛选和排序、图表生成和编辑等。 总之,VB.NET中的Office控件为我们提供了方便、快捷的方法来与Microsoft Office应用程序进行交互。无论是创建个人应用程序还是企业级解决方案,Office控件都能帮助我们实现与Office应用程序的无缝集成,从而提高工作效率和用户体验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值