利用Minidx Extract-Text Com组件从Word,Xls,Pdf……等文件中读取文本内容

不少人对Google,Baidu等搜索引擎可以“找到”你放在服务器上的Word的Doc,Excel的xls以及Pdf等各种文件而感到惊叹不已,也有不少人发来邮件询问我Minidx文件管理器中从各种格式的文件中读取文本内容是如何实现的。Linux平台实现起来比较复杂一些,不过对于Windows用户来说,其实利用微软Ifilter的Indexing service接口,可以比较容易的实现上面的功能。Minidx支持200多种文件格式,其实也是利用了Ifilter的接口。实现的基本原理,就是写一个Com组件,去查找系统中相应文件格式的API接口所在的Dll路径,然后调用抽取文本。

在上面的微软Ifilter中有关于IFilter的基本概念的介绍,这里不再重复,另外在codeproject的Using IFilter in C#中,可以找到C#的实现并且可以下载到源代码。因为性能上的考虑,Minidx文件管理器的这一部分完全利用C++实现,并封装为Com组件,下面主要是对如何通过调用这一Com组件在自己的程序中实现Doc,Xls,Pdf,msg等等文本阅读等功能作一些说明。

●Demo压缩包构造(压缩包可以从这里下载

demo_vb.zip———–demo_vb.sln   整个解决方案(solution)文件

                     |———demo_vb.suo 用户配置文件

          |———demo_vb—-bin——–Debug—-demo_vb.exe   Debug版本目标文件

                                                        |———Release—demo_vb.exe  Release版本目标文件

                                                |—My Project(忽略)

                                                |—obj                       编译生成的临时文件

                                                |—demo_vb.vbproj      工程文件

                                                |—ExtractText.dll         文本抽取Com组件

                                                |—Form1.Designer.vb   Demo的GUI文件

                                                |—Form1.resx                资源文件

                                                |—Form1.vb                   Demo的源代码文件

                                                |—run.bat                      Com组件注册命令

●执行Demo

①、双击run.bat执行,注册Com组件

register

②、双击demo_vb\bin\Release或者demo_vb\bin\Debug目录下的demo_vb.exe

demo-run

③、点“File”,选择对象文件

select-english-file

④、选中文件,查看抽取文本结果。(下面分别是中日英Word的抽取结果)

result-engilsh select-Japanese-file select-Chinese-file

注意:抽取文本对象文件需要有读写权限,正在编辑中的文件抽取文本时可能会出错。

●Demo代码说明

首先当然需要导入Dll组件,下面的代码很简单,也都有注释,应该不难理解,这里不再累述,有什么不明白或者有什么问题的话,可以提出来一起探讨,:)

   1:  '-----------------------------
   2:  ' desc: Extract text from selected file
   3:  '-----------------------------
   4:  Private Sub SelectFileDialog_FileOk(ByVal sender As System.Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles SelectFileDialog.FileOk
   5:          On Error GoTo ErrH
   6:   
   7:          ' get selected full-path file name
   8:          Dim sFile As String = SelectFileDialog.FileName
   9:   
  10:          ' set file name
  11:          txtFilePath.Text = sFile
  12:   
  13:          ' set ExtractText module
  14:          Dim te As ExtractTextLib.TextExtractor = New ExtractTextLib.TextExtractor
  15:          Dim sText As String
  16:          sText = te.ExtractText(sFile, MAX_EXTRACT_TEXT_SIZE)
  17:          Err.Clear()
  18:   
  19:          'Me.FileLength.Text = Len(sText).ToString()
  20:          Me.ExtractText.Text = sText
  21:   
  22:          Exit Sub
  23:  ErrH:
  24:          MsgBox("Error extracting text from '" & sFile & "' Err=" & Err.Number & "-" & Err.Description & " in " & Err.Source)
  25:      End Sub

工程的DLL和Demo源代码从这里下载,C/C++调用的Demo还在制作中,有兴趣的高手们也可以制作Php,Delphi,C#等各种语言调用的Demo以供分享~~,实际上原理是一样的。有什么问题可以直接在这里留言或者在Minidx帮助论坛发贴寻找帮助。该模块可用于任何商业和非商业的用途,如果你愿意的话,可以发一个邮件给我告诉我这一模块被用在了你的项目中,那么当你取得成功的时候,我也可以向我的朋友们吹嘘一下,当然这不是必需的,:)

32 thoughts on “利用Minidx Extract-Text Com组件从Word,Xls,Pdf……等文件中读取文本内容”

  1. Extract.dll和intero.ExtractTextLib.dll两个dll 是什么关系?
    com组件不提供接口说明,大家不指导如何开发啊

  2. 我下了个vc2005的源代码 为什么编译的时候有错——————–Configuration: demo_vc – Win32 Debug——————–
    Compiling…
    demo_vc.cpp
    e:\我的文档\demo_vc2005_wrap\demo_vc2005_wrap\demo_vc\demo_vc.cpp(16) : error C2059: syntax error : ‘&&’
    e:\我的文档\demo_vc2005_wrap\demo_vc2005_wrap\demo_vc\demo_vc.cpp(16) : error C2143: syntax error : missing ‘;’ before ‘}’
    e:\我的文档\demo_vc2005_wrap\demo_vc2005_wrap\demo_vc\demo_vc.cpp(16) : error C2143: syntax error : missing ‘;’ before ‘}’
    e:\我的文档\demo_vc2005_wrap\demo_vc2005_wrap\demo_vc\demo_vc.cpp(17) : error C2143: syntax error : missing ‘;’ before ‘{‘
    e:\我的文档\demo_vc2005_wrap\demo_vc2005_wrap\demo_vc\demo_vc.cpp(17) : error C2447: missing function header (old-style formal list?)
    e:\我的文档\demo_vc2005_wrap\demo_vc2005_wrap\demo_vc\demo_vc.cpp(17) : error C2143: syntax error : missing ‘;’ before ‘}’
    Error executing cl.exe.

  3. @skybright

    你用的是VS2005吗?
    我这里编译没有问题啊

    其实你可以自己创建一个工程,把
    ExtractText.dll
    ExtractText.h
    ExtractText_i.c
    以及demo_vc.cpp的相关几行代码复制过去,组件按照上面的说明注册一下就可以用了。

  4. 您好:我在系統的Lucene全文檢索功能,取用您的ExtractText.dll元件,以截取txt、office格式的附件,很感謝您在網路上釋出這麼好用的軟件。
    請問程式中,宣告MAX_EXTRACT_TEXT_SIZE變數時,指定64M做為讀取文本內容的上限,64M是不是經過測試,所訂立出來的讀取上限呢?或是什麼原因之下,而訂立64M呢?
    謝謝!

  5. 另外請教一個問題,請問ExtractText.dll元件是如何產出的呢?
    1.Microsft元件?2.您撰寫的元件?

  6. 请问,针对Excel,有没有按照某个sheet,每一行的顺序提取出来的。

    目前的方法,是一次性把所有信息提取出来,内容不知道是按照什么顺序提取出来的。

  7. 关于从文件读取文本的问题咨询:
    目前提取文档的接口如下:
    ITextExtractor *te = NULL;
    HRESULT Cohr = CoCreateInstance(CLSID_TextExtractor, NULL, CLSCTX_INPROC_SERVER,IID_ITextExtractor, (void**) &te);
    if(SUCCEEDED(Cohr)&&te)
    {
    te->ExtractText(fileName, 0,&bstr);
    te->Release();
    }
    在使用接口ExtractText析取文本的时候,文件的类型是通过fileName确定的,但我希望ExtractText增加一个参数:filetype(文件类型),这样我可以用自己指定的格式读取文本,例如:
    我有一个text文件,文件名是a.text,但希望使用doc的方式来读取文件,目前我采用的措施是先重命名文件为a.doc,析取文本后再将文件改回a.text,操作比较麻烦,而如果接口添加关于文件类型的参数后,我就不用重命名了。
    不知道您能否提供这样的接口,我目前的一个项目正需要这样的接口,如能提供将不胜感激!!!

  8. 你好,我使用你的com组件,测试文件类型(doc,xls),环境:主机:winxp,office2003;虚拟机:winxp,office2003;在我的主机上是OK的,然后我用虚拟机做测试(winxp),发现CoCreateInstance成功,但是ExtractText总是返回错误E_INVALIDARG;我下载了demo版,放到虚拟机下作测试,也是返回空!
    自己用IFilter Explorer比较了下,发现虚拟机下缺少offfilt.dll,offfiltx.dll,猜想是不是由于office未完全安装的结果;但是我主机和虚拟机都是用自定义安装,然后选中word和excel。
    请教下具体是什么情况

  9. 你好,我用你的代码,读取DOC文件是成功的,但读PDF格式的文件却不成功,“unknow error”

Leave a Reply

Your email address will not be published. Required fields are marked *