OBA实战心得(VSTO + Word 2007 + WSS)

 

实战OBA VSTO+WSS

最近帮朋友忙,用Visual Studio Tools for Office 3.0 + Word2007 + Windows Sharepoint Service实现了一个B/SOffice应用,觉得有必要跟大家分享一下心得。呵呵。

先讲一下需求:

需求是这样的,客户想要构建一个基于Word的信息管理系统。

具体要求如下:

1.                     1.        能把Word文档里的指定内容保存到数据库中

2.                     2.       能随时调取这些保存在数据库中的内容到Word中而编辑成为一份新的文档。

3.                     3.        希望Word文档带有版本管理的功能。

分析:

     需求其实很简单,但做起来就有很多的问题了。笔者遇到的问题如下:

1.                      Word文档是非结构化的,而数据库是结构化的,如何映射?

2.                      Word文档内容的种类是多种多样的,包括图片,Word公式,各种图标,线段等等,如何保存?同时又如何保证上述各种类型的数据保存到数据库中是可“反序列化”的,就是说再从数据库中读出来,放到Word中,还和原来的内容一样(公式还是公式,还可以对公式进行编辑)?

3.                      版本管理可以使用MOSSWSS,但如何与VSTO结合

     上述这些问题都比较棘手,笔者曾经想过几种方案:

1.                      使用OpenXML + Content Control。因为OpenXML是结构化的,并且Content Control可以绑定到自定义的数据。但这种方案又很快被否定了,因为OpenXML的操作不具交互性,不能在打开Word文档的同时进行数据操作。

2.                      使用VSTO + Content ControlVSTO可以方便的对Word进行无缝扩展,方便地操作Word文档。也可以用Content Control进行数据绑定。

     大体方案定了之后,就开始对每一个技术难点进行攻关,找到解决方案:

     1.       如何把非结构化的文档内容保存到结构化的数据库中。

     a.       其实这个问题就是如何对Word文档内容进行结构化的划分,使指定的内容可以映射到数据库的一条记录。最好的方式当然是使用Content Control。因为它可以包括任何的Word内容,而且也可以嵌套,当然是天然的结构化“利器”。并且只要管理好Content Control的命名,即可保存多种内容到数据库中。

     2.       如何把各种类型的内容“序列化”到数据库中但又能“反序列化”到Word中。

这个问题就比较棘手了,要研究Word的内容格式。大家都知道Word采用的是RTF的复文档格式。但如何把RTF格式的内容“序列化”呢?在没有深入研究之前,笔者第一个想法是使用流保存到数据库的二进制字段中。

但事情没那么简单,在笔者研究如何把RTF格式内容转换成流的过程中,发现另一个问题。

如何得到RTF格式的内容

这个问题看起来很简单,有人想,用鼠标选中不就行了吗?其实不然,大家可以去试试,在Word中输入一段文字,再画一条线,或者一个矩形,然后选中试试。这两种内容是不能被同时选中的。

有人又说,用VSTO中的Word Object ModelRange或者Selection对象选中也可以,笔者虽然没尝试,但觉得也跟用鼠标的情况类似。

为此,笔者想到了一个办法,就是使用Content Control。在尝试中,笔者发现Content Control是可以包含任何Word内容的,不管是文字,图片,图形,公式等,都可以包含进来。不过对于刚才提到的线段和矩形,就不能“复制”到Content Control中,但可以拖动到Content Control中,这样Content Control也能自动包含它们。下面是一个图示:

上图中带箭头的线就是我手动拖到Content Control中去的。

RTF内容是包含到Content Control中了,但是如何得到呢,如何“原封不动”地转换成流,这个问题困扰了笔者一段时间。

经过研究,笔者发现了一条“捷径”,可以绕过很多这些麻烦的问题。就是使用“剪贴板”。剪贴板是Windows的基础功能,所有的Windows都支持,VSTO当然也不例外。笔者就发现了VSTORange对象的Copy()方法,可以直接把Range中的内容拷贝到剪贴板中。由于Word也是使用剪贴板来复制/粘贴,所以这样Word内容的RTF格式就不会丢失了。于是笔者使用了Content Control.Range.Copy()方法,把Content Control中的所有内容(包括图标,线段等)复制到剪贴板中。

现在内容是复制到剪贴板中了,下一步就是从剪贴板中取出来。

由于剪贴板中存放的内容格式有很多,所以首先要找出Word内容存储在剪贴板的格式类型。经过笔者研究,Range.Copy()方法把内容用RTF格式复制到剪贴板。所以得到内容的方式就很简单了。使用:

object obj = Clipboard.GetData(System.Windows.Forms.DataFormats.Rtf);

将得到的内容保存到数据库中

得到剪贴板中的内容,笔者监视得到的object,发现原来根本就是一个被“序列化”的字符串。所以,保存此字符串到数据库中就OK了(当然也可以使用流存到二进制字段中)。 

取出保存的内容,添加到Word

至于“反序列化”的过程,使用:Clipboard.SetData(System.Windows.Forms.DataFormats.Rtf, content);

Control Control.Range.Paste();

即可,任何格式的内容都不会丢失。

     3.       如何把VSTOWSS结合

        所谓的VSTOWSS结合,其实就是WSS文档库中的文档都具备我们用VSTO开发好的这些功能。

        这个问题不复杂。只需要做几个步骤。

     a.       发布VSTO

     b.      创建WSS文档库

     c.       WSS中新建一个内容类型

     d.      将新建的内容类型与我们发布的VSTO关联

     e.      将新建的内容类型添加到文档库中

 这样就客户可以在WSS的文档库中新建并打开文档了,第一次新建文档时,会自动安装我们的VSTO 扩展到客户的机器上,就可以使用我们的自定义功能了。

具体结合方法参见:http://exchange.ctocio.com.cn/office/89/8171589.shtml

     下面是一个简单的例子,说明如何添加Content Control并复制和粘贴。 

     WordDocument2.rar

     至此,我们的实战OBA项目就结束了。希望笔者的经历能在大家的OBA开发上有所帮助。

 

posted on 2008-09-10 17:49  zhaojunqi  阅读(3769)  评论(6编辑  收藏  举报

导航