You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 08:30:52