如何在Lotus Notes中搜索.doc/.docx/PDF文件内容?现有代码报错
解决Lotus Notes中搜索.doc/.docx/PDF文件内容的问题
你原代码直接用Input #读取非文本文件(doc/docx/PDF)会报错,因为这些是二进制或结构化格式文件,不是纯文本,无法按行直接读取解析。针对不同文件类型,可采用以下方案:
一、处理.doc/.docx文件
方法1:通过COM对象调用Microsoft Word
Lotus Notes支持COM自动化,可调用Word对象提取文档内容后再做字符串搜索:
Function funcCheckIfStringInDocExist(fileName As String, myString As String) As Integer Dim ws As Variant Dim doc As Variant Dim docText As String Dim position As Integer Set ws = CreateObject("Word.Application") ws.Visible = False '后台运行,不显示Word窗口 On Error GoTo ErrorHandler Set doc = ws.Documents.Open(fileName) docText = doc.Content.Text '提取文档全部文本 position = InStr(docText, myString) funcCheckIfStringInDocExist = (position > 0) doc.Close SaveChanges:=False ws.Quit Set doc = Nothing Set ws = Nothing Exit Function ErrorHandler: funcCheckIfStringInDocExist = False If Not doc Is Nothing Then doc.Close SaveChanges:=False If Not ws Is Nothing Then ws.Quit Set doc = Nothing Set ws = Nothing End Function
方法2:直接解析docx的XML结构(仅docx)
docx本质是压缩包,核心文本存放在word/document.xml中,可利用Lotus Notes的Zip类(需Notes 8.5+)解压读取:
Function funcCheckIfStringInDocxExist(fileName As String, myString As String) As Integer Dim zip As Variant Dim entry As Variant Dim xmlText As String Dim cleanText As String Dim position As Integer Set zip = CreateObject("Notes.Zip") zip.Open(fileName, 1) '1表示只读打开 For Each entry In zip.Entries If entry.Name = "word/document.xml" Then xmlText = entry.ReadText() '清理XML标签,避免干扰搜索 cleanText = Replace(xmlText, "<[^>]+>", "", 1, -1, 1) position = InStr(cleanText, myString) funcCheckIfStringInDocxExist = (position > 0) zip.Close Exit Function End If Next funcCheckIfStringInDocxExist = False zip.Close Set zip = Nothing End Function
该方法无需依赖Word,但需额外清理XML标签以提高搜索准确性。
二、处理PDF文件
方法1:调用Adobe Acrobat的COM对象
若客户端安装了Adobe Acrobat(非Reader版本),可通过COM对象提取PDF文本:
Function funcCheckIfStringInPDFExist(fileName As String, myString As String) As Integer Dim acroApp As Variant Dim acroDoc As Variant Dim fullText As String Dim i As Integer Dim position As Integer Set acroApp = CreateObject("AcroExch.App") Set acroDoc = CreateObject("AcroExch.PDDoc") On Error GoTo ErrorHandler If acroDoc.Open(fileName) Then For i = 0 To acroDoc.GetNumPages() - 1 Dim page As Variant Dim pdText As Variant Set page = acroDoc.AcquirePage(i) Set pdText = CreateObject("AcroExch.PDTextSelect") pdText = page.CreatePageTextSelect(0, 0, page.GetMediaBox().Right, page.GetMediaBox().Top) fullText = fullText & pdText.Text Set pdText = Nothing Set page = Nothing Next position = InStr(fullText, myString) funcCheckIfStringInPDFExist = (position > 0) acroDoc.Close Else funcCheckIfStringInPDFExist = False End If acroApp.Exit Set acroDoc = Nothing Set acroApp = Nothing Exit Function ErrorHandler: funcCheckIfStringInPDFExist = False If Not acroDoc Is Nothing Then acroDoc.Close If Not acroApp Is Nothing Then acroApp.Exit Set acroDoc = Nothing Set acroApp = Nothing End Function
方法2:使用第三方命令行工具
若不想依赖Acrobat,可借助pdftotext这类开源工具,先将PDF转成TXT再用原文本搜索逻辑:
Function funcCheckIfStringInPDFViaCmd(fileName As String, myString As String) As Integer Dim shell As Variant Dim tempTxt As String Dim filenum As Integer Dim myRecord As String Dim position As Integer tempTxt = Environ("TEMP") & "\temp_pdf_text.txt" Set shell = CreateObject("WScript.Shell") '调用pdftotext,需确保工具在系统PATH中 shell.Run "pdftotext """ & fileName & """ """ & tempTxt & """", 0, True filenum = FreeFile() Open tempTxt For Input As #filenum Do Until EOF(filenum) Line Input #filenum, myRecord position = InStr(myRecord, myString) If position > 0 Then funcCheckIfStringInPDFViaCmd = True Close #filenum Kill tempTxt '删除临时文件 Exit Function End If Loop Close #filenum Kill tempTxt funcCheckIfStringInPDFViaCmd = False Set shell = Nothing End Function
三、整合到原代码中
需先判断文件后缀,再调用对应处理函数:
Do While fileName$ <> "" Dim ext As String ext = LCase(Right(fileName, 4)) '获取文件后缀(如.txt、.docx) varCheckIfStringInFileExist = False Select Case ext Case ".txt" varCheckIfStringInFileExist = funcCheckIfStrinInFileExist(fileName, myString) Case ".doc" varCheckIfStringInFileExist = funcCheckIfStringInDocExist(fileName, myString) Case "docx" varCheckIfStringInFileExist = funcCheckIfStringInDocxExist(fileName, myString) Case ".pdf" varCheckIfStringInFileExist = funcCheckIfStringInPDFExist(fileName, myString) '或使用命令行方法:varCheckIfStringInFileExist = funcCheckIfStringInPDFViaCmd(fileName, myString) End Select If varCheckIfStringInFileExist Then Messagebox "找到文本的文件:" + fileName End If fileName$ = Dir$() Loop
注意事项
- COM对象调用需客户端安装对应软件(Word/Acrobat),否则会触发报错。
- 解析docx的XML方法需清理标签,避免标签文本干扰搜索结果。
- 命令行工具方法需确保工具可被系统访问,且程序有创建临时文件的权限。
内容的提问来源于stack exchange,提问作者ibotsios
相关产品推荐
相关产品推荐

