【ITPUB 技术文档】
Lotus Symphony 是可免费使用的具备丰富功能的文档编辑工具, 可以选择集成在Notes中或者独立运行。在 Lotus Notes 中可以从 Open 菜单打开该编辑器,也可以在应用程序中以编程方式打开编辑器。而且它们的图标将出现在计算机桌面及 Start 菜单中,因此产品编辑器的使用可以独立于 Lotus Notes。有三个编辑器可处理文档、电子表格和描述,如图 1-3 所示。它们具有直观的用户界面,以基于 Eclipse 的应用程序为特点,支持开放式文档格式(Open Document Format,简称ODF),与各种文档格式兼容(Microsoft Office, OpenOffice, Lotus SmartSuite等),可以把编辑的文档直接导出成Adobe Acrobat (PDF) 格式, 支持多种平台(Windows, Linux ,Mac ),更重要的是Lotus Symphony具有开放的接口,可以进行灵活的定制和各种业务和协作应用集成。
图 1. IBM Lotus Documents
图 2. IBM Lotus Presentations
图 3. IBM Lotus Spreadsheet
本文结合实例,系统而详细地介绍了如在 Notes 复合应用中使用 Lotus Symphony。下面,让我们通过一个相对简单的实例如 图 4 所示,来介绍如何在 Notes 复合应用中使用 Lotus Symphony 应用实例。
图 4. 复合应用实例
这是一个用 Notes 8 打开的应用(TopCustomer.nsf),你一眼能看出它和过去你所见到 Notes 的帧结构、视图、表单等等这些元素全不相同但又似曾相识。在这个应用中,你看到了左方展示公司客户列表的 Notes 视图。看到了右方展示 Lotus Symphony 文档编辑器的 Eclipse 插件。所有这些东西(当然,它们有个正式的名称——组件),为了一个业务目的(2007 年的非常好的客户名单)而组装在一起,这就构成了一个复合应用。不只是组装,组件之间还可以传递消息。还是看上面这个例子,当我们点击左方客户列表中的某个客户时,会把该客户的公司名称传递给其他组件,这样右方的 Lotus Symphony 文档编辑器会把传递来的公司的名称插入到当前的光标位置。 图 5 展示了消息在 Property Broker 编程模型中传递的后台过程。
图 5. Property Broker 编程模型
在这里我们不过多的讲述复合应用的概念,大家可以从文章后面的参考资料里获得更多的关于 Notes 复合应用的详细信息。
在 Notes 8 中创建一个复合应用是非常简单的一件事情,因为基于 NSF 的复合应用就是一个 NSF 数据库,在创建时,和一个传统的 NSF 数据库没有什么区别。所不同的是选择模板时必须选择空白组合应用程序模板,如 图 6 所示。
图 6. 在 Notes 8 中创建复合应用
创建之后,你将得到一个空白的复合应用页面如 图 7 所示。
图 7. 空白的复合应用页面
接下来点击 操作(Actions)中的 编辑复合应用(Edit Application),Notes 8 会启动 CAE(Composite Application Editor)如 图 8 所示。通过这个工具,你可以把 NSF 组件或者 Eclipse 组件拖拽到这个复合应用的页面上。此外,通过这个工具,你也可以创建多页面的复合应用。
图 8. 复合应用编辑器
创建空白复合应用 NSF,然后填充组件,这就是创建一个复合应用的过程。这个过程本身并不复杂,我们需要面对的非常关键的问题是如何开发那些满足复合应用特性的 NSF 组件和 Eclipse 组件。
当然很多情况下,只依靠 NSF 组件构建 Notes 8 复合应用是不够的。在做报表展现,图形处理,以及一些其他业务应用的时候,传统 Notes 开发会遇到一些瓶颈。在 Notes 8 中,我们可以通过 Eclipse 组件来弥补 NSF 组件功能上的不足。Notes 8 中新加入的文档编辑工具 Lotus Symphony 源自 Open Office 1.1 ,是基于 Lotus Expeditor 平台的一个 Eclipse 的插件应用。换句话说,本质上 Lotus Symphony 就是一个大的 Eclipse 插件包。因为 Lotus Symphony 是基于 Eclipse 插件结构 ,所以我们可以把它做成一个 Eclipse 组件来丰富复合应用的功能。开发复合应用的 Eclipse 组件需要具有 Eclipse 的插件(plug-in)开发技能。关于 Eclipse 插件开发细则以及 Eclipse 组件开发环境的配置,请参考 http://www.eclipse.org 上的相关文档,此处不再赘述。
与 NSF 组件一样,Eclipse 组件的开发同样遵循着 定义属性和操作,属性的发布,操作的实现 三个步骤。在最新版本的 Notes 8 中 Lotus Symphony 已经为复合应用提供了一个默认的 Symphony 组件 Symphony View 如 图 12 所示。
图 12. 默认的 Symphony 组件 Symphony View
如果你所得到的 Notes 8 不是最新版,你所看到的组件选用板会和上图不一样,不过那也没有关系,默认的 Symphony View 还是存在的,大家可以参照下面的复合应用组装章节,来添加默认的 Symphony 组件到我们的复合应用中去。
Eclipse 组件中同样使用 WSDL 来描述组件的属性和操作,并且其格式与 NSF 组件的完全一致。默认的 Symphony 组件属性和操作的定义文件位于 <notes install directory>\framework\shared\eclipse\plugins\ com.ibm.productivity.tools.ui.views_1.0.0.20071130-2008\views.wsdl 这里我们定义了四个属性,其中两个属性为对外发布,另外两个属性为接收其他组件传来的消息。
当我们保存当前编辑文档时对外发送一个属性:文档保存的路径(FileSaved_Message),该属性的类型为统一资源定位符(URL),对应操作 FileSaved_Operation;当我们对文档里的文本对象做选择时对外发送一个属性:当前选择的文本(SelectionChanged_Message),该属性类型为字符串(String)对应操作 SelectionChanged_Operation;当我们要打开其它组件指定的文档时要接收一个属性:指定文档的路径(LoadFile_Message),该属性的类型为统一资源定位符(URL),对应操作 LoadFile_Operation;当我们要往当前文档光标位置插入指定字符串时要接收一个属性:指定的字符串(Insert_Message),该属性类型为字符串(String)对应操作Insert_Operation。
作为一个 Notes 视图,它本身提供了将所有客户按公司名列举的功能,我们希望它能够在单击视图中的每个客户文档时,对外发送一个属性:该客户的公司名称,该属性的类型为字符串(String)。同时我们希望它能够在单击视图中一个按钮时, 对外发送一个属性:非常好的客户列表的模板的路径,该属性的类型为统一资源定位符(URL)。Symphony 组件定义的属性如 清单 3 所示。Symphony 组件定义的操作如 清单 4 所示。
清单 3. Symphony 组件定义的属性
<message name="FileSaved_Message"> <part name="FileSaved_Part" type="idt:url"/> </message> <message name="Insert_Message"> <part name="Insert_Part" type="xsd:string"/> </message> <message name="LoadFile_Message"> <part name="LoadFile_Part" type="idt:url"/> </message> <message name="SelectionChanged_Message"> <part name="SelectionChanged_Part" type="xsd:string"/> </message> |
清单 4. Symphony 组件定义的操作
<operation name="FileSaved_Operation"> <portlet:action name="FileSaved" caption="FileSaved.caption" description="FileSaved.description"/> <output> <portlet:param name="FileSaved" partname="FileSaved_Part" caption="FileSaved.caption" description="FileSaved.description"/> </output> </operation> <operation name="SelectionChanged_Operation"> <portlet:action name="SelectionChanged" caption="SelectionChanged.caption" description="SelectionChanged.description"/> <output> <portlet:param name="SelectionChanged" partname="SelectionChanged_Part" caption="SelectionChanged.caption" description="SelectionChanged.description"/> </output> </operation> <operation name="Insert_Operation"> <portlet:action name="Insert" caption="Insert.caption" description="Insert.description"/> <input> <portlet:param name="Text" partname="Insert_Part" caption="InsertText.caption" description="InsertText.description"/> </input> </operation> <operation name="LoadFile_Operation"> <portlet:action name="LoadFile" caption="LoadFile.caption" description="LoadFile.description"/> <input> <portlet:param name="FileLocation" partname="LoadFile_Part" caption="FileURLType.caption" description="FileURLType.description"/> </input> </operation> |
相应的操作实现代码都已经封装在了 Lotus Symphony 插件包里。Lotus Symphony 通过这些属性和操作为复合应用提供了简单接口,给复合应用提供了简单的文档编辑能力:打开,保存文档,插入字符串,获取当前选择文本。当我们要更加紧密地实现 NSF 组件和 Lotus Symphony 组件之间的集成时我们就需要通过 Lotus Symphony API 来编写 Eclipse 组件定制 Lotus Symphony,从而提供更多的接口与功能给其他复合应用的组件。我们会在另一篇文章里介绍如何使用 Lotus Symphony API 来开发定制 Lotus Symphony。
我们这个应用实例是为了完成一个业务目的:创建 2007 年的非常好的客户名单。为此我们需要制作一个客户名单的模板。请大家查看我们在前面的 LotusScript 代码中用到的一行代码:pb.setPropertyValue("Idtable","file:\\\C:\IdTable.odt")
。其中 file:\\\C:\IdTable.odt 就是模板的存放地址。如 图 13 所示模板中包含一个大标题和一个存放客户名称的表格。大家可以自行创建自己需要的模板格式,添加新的元素。
创建好了复合应用,开发好了组件,接下来就可以将这些组件加入到复合应用中,并进行组装了。回到复合应用的编辑界面 CAE(Composite Application Editor)中,右边的 sidebar 是组件选用板如 图 14 所示。PIM 栏中列举出了 Notes 8 中提供的开箱即用的组件,主要是邮件,日历,待办等内容,常规栏中则是用户自定义的组件。右键菜单中点击 添加组件,可以选择 添加 NSF 组件 还是 Eclipse 组件。其中 Eclipse 组件又分为了 来自更新站点的,或者是 来自于本地的 两种。后者在 Eclipse 组件的开发调试过程中使用的比较多,正式使用时,一般会将 Eclipse 组件打包放到一个更新站点上,客户端可以自动下载安装。
图 14. 组件选用板
添加 NSF 组件时需要指定组件的名称,描述,以及 Notes URL 如 图 15 所示。如果不熟悉 Notes URL 的写法,可以通过浏览的方式获取对象的 Notes URL 如 图 16 所示。
图 15. 加入 NSF 组件
在我们的应用实例中,All by Company 视图是带有导航栏的我们可以通过在 Notes URL 后面添加参数 &HideNavigator
来隐藏导航栏。
图 16. 寻找组件对象
因为默认的 Lotus Symphony 组件已经被安装到了本地,所以我们通过 来自本地 选项来添加 Lotus Symphony 组件如 图 17 所示,其中 DefaultRichDocumentView 就是默认的 Lotus Symphony 组件(它和我们前面提到的最新 Notes 8 版本里的 Symphony View 是同一个组件,只是新老版本的名称不一样而已)。
图 17. 加入 Eclipse 组件(从本地已安装组件)
现在我们就可以通过拖拽的方式将组件选用板上的组件添加到复合应用中去了。各个组件的位置也可以通过拖拽的方式进行调整。
图 18. 调整组件位置
在确定好组件的布局之后,接下来的工作是非常关键的一步:连接。前文我们说到了 Property Broker 编程模式,其中一个基本的设计理念是:组件之间需要进行连接(Wiring)以匹配属性和操作。而 CAE 中提供了可视化的界面帮助开发者快速进行组件之间的连接如 图 19 所示。
图 19. 连接(Wiring)
在复合应用的组件名称处右键点击菜单进入连接界面。在这个图形界面中,用户可以直接在类型匹配(属性名称可以不一致)的属性和操作之间连线,从而将各个组件有机的联系在一起,实现应用的复合。复合,但绝不复杂,大部分的时候,它就是这么简单!
Lotus Symphony 的 LotusScript 支持
Lotus Notes 是一个强大的协作、工作流平台,很多厂商都把自己的业务建立在它的基础之上。一直以来 Notes 与 文档编辑软件的集成都是很多厂商所关注的问题。大家所熟悉的 Lotus Notes 与 Microsoft Office 或者 OpenOffice 在 Windows 操作系统中的集成都是通过 COM 调用来实现的。这些集成提高了用户的工作效率,增加了各个软件的可用性。在 Notes 8 中 IBM 的免费文档编辑器 Lotus Symphony 被作为一个组件紧密整合到了 Notes 中,给软件开发商和客户们提供了一种全新的更好的 Notes-office 集成方案。虽然我们有很多种方式来实现 Lotus Notes 与 Lotus Symphony 的集成。但是 LotusScript 始终是关键的一种:
- LotusScript 是 Notes 中最重要的编程语言,它已经被 Notes 开发人员广泛的使用。
- Lotus Symphony 通过 StartBasic 的方式提供对 LotusScript 的支持。StartBasic 是 OpenOffice 的脚本语言,通过它可以访问几乎所有的 LotusSymphony 提供的功能。
- StartBasic 的代码可以直接在 LotusScript 环境中执行。这是因为 LotusScript 可以直接访问 COM 对象,并且 Lotus Symphony 提供了 UNO 对象和 COM 对象的映射。
注:要使用此功能请使用 Notes 8.0.1 以上的版本
在 清单 5 中所列的 LotusScript 代码实现了,在当前编辑文档中插入一个带有数据的表格的操作。
清单 5. Symphony 组件定义的操作
Sub Click(Source As Button) Set objServiceManager = CreateObject("com.sun.star.ServiceManager") Set objCoreReflection= objServiceManager.createInstance("com.sun.star.reflection.CoreReflection") Set objDesktop = objServiceManager.createInstance("com.sun.star.frame.Desktop") Dim args() Set objFrame=objDesktop.getCurrentFrame() Set objDocument=objDesktop.getCurrentComponent () Set objText = objDocument.getText() Set objCursor = objText.createTextCursor() objText.insertString objCursor, "The Sales History Of This company", False Set objTable= objDocument.createInstance( "com.sun.star.text.TextTable") objTable.initialize 4, 4 'Insert the table objText.insertTextContent objCursor, objTable, False 'Get first row Set objRows= objTable.getRows() Set objRow= objRows.getByIndex(0) 'Set the table background color objTable.setPropertyValue "BackTransparent", False objTable.setPropertyValue "BackColor", 13421823 'Set a different background color for the first row objRow.setPropertyValue "BackTransparent", False objRow.setPropertyValue "BackColor", 6710932 'Fill the first table row objTable.getCellByName("A2").setValue 22.5 objTable.getCellByName("B2").setValue 5615.3 objTable.getCellByName("C2").setValue -2315.7 objTable.getCellByName("D2").setFormula"sum <A2:C2>" objTable.getCellByName("A3").setValue 21.5 objTable.getCellByName("B3").setValue 615.3 objTable.getCellByName("C3").setValue -315.7 objTable.getCellByName("D3").setFormula "sum <A3:C3>" objTable.getCellByName("A4").setValue 121.5 objTable.getCellByName("B4").setValue -615.3 objTable.getCellByName("C4").setValue 415.7 objTable.getCellByName("D4").setFormula "sum <A4:C4>" 'Create a paragraph break ( ControlCharacter::PARAGRAPH_BREAK). 'objText.insertControlCharacter objCursor, 0, False On Error Resume Next If Err Then Msgbox "An error occurred" End If End Sub |
在代码中我们看到,我们通过 CreateObject("com.sun.star.ServiceManager")
方法获得 LotusSymphony 的一个实例。通过 objDocument.createInstance( "com.sun.star.text.TextTable")
来创建一个表格,然后把一些数据填充进这个表格中。这里不对 StartBasic 做更多的解释了,请大家参看 OpenOffice SDK。对广大 Notes 开发人员而言,用 LotusScript 来访问 Lotus Symphony 的方式实现起来更容易上手。