Notes 数据库是一种文档型数据库,其中文档的富文本域中往往嵌入许多附件(如 Word 文档、PDF 文档、Excel 文档等)。这些附件常常是工作的重要资料,用户时常需要导出这些附件到其他系统中进行处理,如图 1 所示,用户可以将所选中的附件或者该文档中的所有附件保存到本地系统。有时用户还需要导出多个文档中的附件,如图 2 所示,每个文档中都嵌入了附件,用户需要将所选中的所有文档中的附件全部导出。在这种情况下,用户只能手动逐个打开各个文档并将附件导出到系统本地,然后再将附件导入到其他系统中,这大大降低了效率。下文分析了若干附件批量导出的需求以及相应的解决方案。
图 1. Notes 文档中附件的导出
图 2. 多 Notes 文档中附件的导出
附件批量导出的需求及其解决方案1. 导出到本地系统中
举一例说明。某公司用 Excel 表单作为公司的报表管理系统,它们的业务流程是:首先,公司定期下发 Excel 报表模板供全公司使用。然后,基层的业务人员在每个周期的期末要定期填写报表,即在模板里面填写数据,然后新建一个 Notes 文档,把这个 Excel 文件嵌入到这个文档中提交。最后,公司的信息收集人员需要从每个 Notes 文档中导出 Excel 文件,再对这些报表进行手工汇总和处理。显然,如果业务人员数量大,那么 Notes 文档就会很多,这种手工导出附件的方式最终将不堪重负。本文开发了一个 SaveToLocalSystem Agent 程序,它可以将 Notes 数据库中被选中的文档中的附件批量导出到指定的系统目录下。这个 agent 是用 LotusScript 编写的,见代码清单 1,也可以使用 Java API 编写。本文附件 attachment.nsf 中包含 SaveToLocalSystem Agent 程序及测试数据。
清单 1. 多 Notes 文档中附件批量导出到本地系统 Type BROWSEINFO hOwner As Long pidlRoot As Long pszDisplayName As String lpszTitle As String ulFlags As Long lpfn As Long lParam As Long iImage As Long End Type Const BIF_RETURNONLYFSDIRS = &H1 Const BIF_DONTGOBELOWDOMAIN = &H2 Const BIF_STATUSTEXT = &H4 Const BIF_RETURNFSANCESTORS = &H8 Const BIF_BROWSEFORCOMPUTER = &H1000 Const BIF_BROWSEFORPRINTER = &H2000 Const MAX_PATH = 260 Declare Function SHGetPathFromIDList Lib "shell32" Alias "SHGetPathFromIDListA" (ByVal pidl As Long, ByVal pszPath As String) As Long Declare Function SHBrowseForFolder Lib "shell32" Alias "SHBrowseForFolderA" (lpBrowseInfo As BROWSEINFO) As Long Declare Sub CoTaskMemFree Lib "ole32" (ByVal pv As Long) Declare Function GetDesktopWindow Lib "user32" () As Long Sub Initialize() Dim session As New NotesSession Dim db As NotesDatabase Dim collection As NotesDocumentCollection Dim doc As NotesDocument Dim rtitem As Variant Dim NotesItem As NotesItem Dim bi As BROWSEINFO Dim pidl As Long Dim path As String Dim pos As Integer bi.hOwner = GetDesktopWindow() bi.pidlRoot = 0& bi.lpszTitle = "Select directory to save the attachments" bi.ulFlags = BIF_RETURNONLYFSDIRS pidl = SHBrowseForFolder(bi) path = Space$(MAX_PATH) If SHGetPathFromIDList(ByVal pidl, ByVal path) Then pos = InStr(path, Chr$(0)) End If Call CoTaskMemFree(pidl) Set db = session.CurrentDatabase Set collection = db.UnprocessedDocuments Set doc = collection.GetFirstDocument() While Not(doc Is Nothing) // 此处假定附件是嵌入在 Body 域当中,当然也可以循环文档所有的域,然后对于富文本域进行处理,提取附件 Set rtitem = doc.GetFirstItem( "Body" ) If ( rtitem.Type = RICHTEXT ) Then ForAll o In rtitem.EmbeddedObjects If ( o.Type = EMBED_ATTACHMENT ) Then Call o.ExtractFile( Left(path, pos - 1) & "\" & o.Name ) End If End ForAll End If Set doc = collection.GetNextDocument(doc) Wend End Sub
使用操作说明:将 SaveToLocalSystem Agent 添加到任意 Notes 数据库中,然后在任意的 view 中选择需要导出附件的文档,再点击菜单 Actions 当中的 SaveToLocalSystem,这时会弹出一个对话框来选择存储目录,如图 3 所示,选好后点击确定,所选文档中的附件就会被导出到所选目录下了。




