当前位置: 首页 > 工具软件 > WPS2CHM > 使用案例 >

C# 文件搜索过程中如何提取office文件,wps,pdf,html,eml等格式的文件正文

艾浩穰
2023-12-01

在文件数据挖掘处理技术中,如何从文本数据中抽取有价值的信息和知识是一个重要的数据挖据分支,是机器学习、自然语言处理、数理统计的基础技术之一,是信息检索,机器学习,AI智能等高端技术的的底层技术支持之一。

本组件智能分析提取其他各种文件中文本,为自然语言信息检索,机器学习等高端技术提供底层支持的技术组件,是Lucene/CLucene, Elasticsearch, Sphinx等全文检索工具,OA, ERP, CRM,网盘,文件管理等其他系统提供文件摘要及搜索前置服务。同时也可以为安全网关,邮件内容监控,内网安全等系统提供文件搜索及监控服务底层技术支持。   

组件提供C#使用组件对大量文件进行文件内容的搜索,为Lucene.Net等提供底层技术支持。系统调用简单方便,效率高。

以下几个步骤即可:

1:  解压直接打开graccvsTest工程

2:  到官网下载graccvs64.dll保存到EXE执行程序所在文件夹下, DLL下载地址

3:  代码中从64行开始定义函数, 从258行是文件取正文示例, testToTextFile函数可以直接输入文件名称函数提取正文并保存为文本文件,  testToString输入rft, html, pdf等文件名称放回字符串. 示例中还提供直接下载HTTP文件并提取正文的方法,使用超级简单.

4: 免费版可以提取50%-80%的文本,基本够用了。

5:  可以下载完整工程包直接测试,   工程下载地址

6:  以下是代码

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Threading;


namespace graccvsTest
{
    public class DllInvoke
    {   
        [DllImport("kernel32.dll")]
        private extern static IntPtr LoadLibrary(string path);

        [DllImport("kernel32.dll")]
        private extern static IntPtr GetProcAddress(IntPtr lib, string funcName);

        [DllImport("kernel32.dll")]
        private extern static bool FreeLibrary(IntPtr lib);
        
        private IntPtr hLib;
        public DllInvoke(String DLLPath)
        {
            hLib = LoadLibrary(DLLPath);
        }

        ~DllInvoke()
        {
            if (hLib != null)
            {
                FreeLibrary(hLib);
            } 
        }
         
        public Delegate Invoke(string APIName, Type t)
        {
            if (hLib != null)
            {
                IntPtr api = GetProcAddress(hLib, APIName);
                return (Delegate)Marshal.GetDelegateForFunctionPointer(api, t);
            }
            else
            {
                return null;
            }
        } 
    }
      
    class Program
    {
        //--------------------------------函数定义--------------------------------
        // 加载DLL,设置动态库需要的临时文件夹,且对此文件夹要有读写权限
        public delegate void LOAD(IntPtr tempPathPtr);

        /*
          注册软件:
          方式1:输入参数,corp为公司名称licText为注册码
          方式2:把授权文件grauth.lic保存到动态库相同文件夹,调用TAuth函数(corp, licText都为空)系统自动加载grauth.lic
          返回值:
            0:免费版本许可为空
            1:许可正常
            2:序列号(公司授权名称)错误
            3:加密数据格式错误
            4:许可过期
            5:许可验证错误
            6:无效的许可
            7:未知错误

          注1:如果注册失败,系统变为免费版本
          注2:免费版也需要调用此函数,corp和licText都为空
        */
        public delegate Int32 AUTH(IntPtr corp, IntPtr licText);

        // 提供文件正文,并保存到目标文件
        // inFilePtr输入文件指针, outFilePtr为TXT目标文件文件指针
        public delegate Int32 TOTEXTFILE(IntPtr inFilePtr, IntPtr outFilePtr);
        // 提供文件正文
        // inFilePtr输入文件指针, 返回UTF-8编码字符串数据指针(此指针需要使用FREESTRING函数释放内存)
        public delegate IntPtr TOSTRING(IntPtr inFilePtr);
        // 释放TOSTRING等函数的返回指针
        public delegate void FREESTRING(IntPtr p);
        // 得到最后的错误信息
        public delegate IntPtr LASTERR();

        // 提取Http/Https文件,返回字符串数据指针
        // url=Http/Https地址
        // fileExt=文件类型(比如:".pdf"),
        // timeout=超时设置,超过此数值系统终止下载文件。单位为毫秒,默认为0(等待文件下载直到完成)
        // httpParams=JSON格式header数据和cookie数据,默认为空
        /*   
          JSON格式如下:
          {"headers":
          [{名称1: 值1},{名称2: 值2},...],
          "cookies":[
          {"name": 名称(字符串), "value": 值(字符串), "expires": 有效期(整数,单位毫秒),
          "path": 路径(字符串), "domain": 域名(字符串)},
          {"name": 名称(字符串), "value": 值(字符串), "expires": 有效期(整数,单位毫秒),
          "path": 路径(字符串), "domain": 域名(字符串)}
          ...
          ]}
          例如:
          {"headers":[{"client_id": "g01x9"}, {"client_secret": "e23c89cc9fe"}, {"client_index": 10092}],
          "cookies":[{"name": "ga", "value": "1020", "expires":36000000, "path": "/hx/", "domain":"www.gaya-soft.cn"},
          {"name": "xc3", "value": "10099", "expires":240000, "path": "", "domain":""}]}
        */
        // 返回UTF-8编码字符串数据指针(此指针需要使用FREESTRING函数释放内存)
        public delegate IntPtr HTTPTOSTRING(IntPtr url, IntPtr fileExt, Int32 timeout, IntPtr httpParams);

        // 下载Http文件,并提取文本,保存到目标文件u
        // outfile为TXT目标文件文件指针,其他参数和HTTPTOSTRING参数相同
        public delegate Int32 HTTPTOTEXTFILE(IntPtr url, IntPtr fileExt, IntPtr outfile, Int32 timeout, IntPtr httpParams);

        //---------------------异步批量处理相关函数---------------------
        // 文件提取异步任务, Infile输入文件地址, Outfile为TXT目标文件文件
        // 如果提取某个文件错误,则 Outfile的内容如下格式: @ErrCode:错误代码, ErrMessage:错误提示
        public delegate void ADDTASK(IntPtr inFilePtr, IntPtr outTxtFilePtr);
        // 异步提取Http文件任务,参数同 HTTPTOTEXTFILE 函数
        public delegate void  ADDHTTPTASK(IntPtr url, IntPtr fileExt, IntPtr outTxtFile, Int32 timeout, IntPtr httpParams);  
        // 开始执行异步任务,返回值=1开始执行, 其他值未识别
        // =2 免费版不支持此功能,=3 没有可以执行的任务 ,=4 当前任务未完成
        public delegate Int32 ASYNCSTART();  
        // 停止任务
        public delegate void ASYNCSTOP();  
        // 一直等待,直到全部异步任务结束
        public delegate void ASYNCWAIT();  
        // 得到执行异步任务的状态, =0 没开始, =1 正在处理中,=2 已中断, =99 处理完成
        public delegate Int32 ASYNCSTATE(); 
        // 设置执行异步任务的CPU数量(不大于软件授权数量),返回软件授权数量
        public delegate Int32 ASYNCMAXPROCS(Int32 num);  
        //---------------------异步批量处理相关函数---------------------

        // 关闭动态库前调用此函数释放资源,否则关闭DLL会发生错误
        public delegate void UNLOAD();
        //--------------------------------以上为函数定义--------------------------------


        //--------------------------------函数变量--------------------------------
        static private DllInvoke dll;
        static private LOAD load;
        static private AUTH auth;
        static private LASTERR lastErr;
        static private FREESTRING freeString; 
        static private TOTEXTFILE toTextFile;
        static private TOSTRING toString;
        static private HTTPTOSTRING httpToString;
        static private HTTPTOTEXTFILE httpToTextFile;
        static private ADDTASK addTask;
        static private ADDHTTPTASK addHttpTask;
        static private ASYNCSTART asyncStart;
        static private ASYNCSTOP asyncStop;
        static private ASYNCWAIT asyncWait;
        static private ASYNCSTATE asyncState;
        static private ASYNCMAXPROCS asyncMaxProcs;
        static private UNLOAD unload;
        //--------------------------------函数变量--------------------------------

        static public bool loadAllFun()
        { 
            load = (LOAD)dll.Invoke("Load", typeof(LOAD));
            auth = (AUTH)dll.Invoke("Auth", typeof(AUTH));
            lastErr = (LASTERR)dll.Invoke("LastErr", typeof(LASTERR));
            freeString = (FREESTRING)dll.Invoke("FreeString", typeof(FREESTRING));
            toString = (TOSTRING)dll.Invoke("ToString", typeof(TOSTRING)); 
            toTextFile = (TOTEXTFILE)dll.Invoke("ToTextFile", typeof(TOTEXTFILE));
            httpToString = (HTTPTOSTRING)dll.Invoke("HttpToString", typeof(HTTPTOSTRING));
            httpToTextFile = (HTTPTOTEXTFILE)dll.Invoke("HttpToTextFile", typeof(HTTPTOTEXTFILE));
            addTask = (ADDTASK)dll.Invoke("AddTask", typeof(ADDTASK));
            addHttpTask = (ADDHTTPTASK)dll.Invoke("AddHttpTask", typeof(ADDHTTPTASK));
            asyncStart = (ASYNCSTART)dll.Invoke("AsyncStart", typeof(ASYNCSTART));
            asyncStop = (ASYNCSTOP)dll.Invoke("AsyncStop", typeof(ASYNCSTOP));
            asyncWait = (ASYNCWAIT)dll.Invoke("AsyncWait", typeof(ASYNCWAIT));
            asyncState = (ASYNCSTATE)dll.Invoke("AsyncState", typeof(ASYNCSTATE));
            asyncMaxProcs = (ASYNCMAXPROCS)dll.Invoke("AsyncMaxProcs", typeof(ASYNCMAXPROCS));
            unload = (UNLOAD)dll.Invoke("Unload", typeof(UNLOAD));

            if(load ==null || unload == null )
            {
                return false;
            }
            else
            {
                return true;
            }
        }

        public enum DllErrCode
        {
            TFE_OK = 0,
            TFE_UNKNOW = 1,
            TFE_FILE_NOTEXIST = 2,
            TFE_SAVE_ERROR = 3,
            TFE_OUTSIZE = 4,
            TFE_UNSUPPORTED = 5,
            TFE_ERROR_INTERFACE = 6,
            TFE_HTTP_ERR = 7,
            TFE_HTTP_FILE_NULL = 8,
            TFE_LICENCE_ERR = 9
        }

        // 根据错误类型返回错误信息
        public static string codeText(Int32 code)
        {
            switch ((DllErrCode)code)
            {
                case DllErrCode.TFE_OK:
                    return "ok";
                case DllErrCode.TFE_UNKNOW:
                    return "未知错误";
                case DllErrCode.TFE_FILE_NOTEXIST:
                    return "提取源文件不存在";
                case DllErrCode.TFE_SAVE_ERROR:
                    return "保存目标文件失败";
                case DllErrCode.TFE_OUTSIZE:
                    return "提取的源文件超出设置的大小范围";
                case DllErrCode.TFE_UNSUPPORTED:
                    return "不支持的提取文件格式";
                case DllErrCode.TFE_ERROR_INTERFACE:
                    return "得到接口失败";
                case DllErrCode.TFE_HTTP_ERR:
                    return "HTTP下载文件失败";
                case DllErrCode.TFE_HTTP_FILE_NULL:
                    return "HTTP文件为空";
                case DllErrCode.TFE_LICENCE_ERR:
                    return "软件许可错误";
                default:
                    return "未知错误2";
            }
        }

        //转换为byte[] 为指针,输入byte[]可以避免忘记释放导致的问题
        static IntPtr stringToUtf8Pointer(byte[] bts)
        {  
            return Marshal.UnsafeAddrOfPinnedArrayElement(bts, 0); 
        }

        //utf8指针转换为字符串
        static string utf8PointerToString(IntPtr p)
        {
            string s = Marshal.PtrToStringAnsi(p);
            //
            byte[] bytes = Encoding.UTF8.GetBytes(s);
            bytes = Encoding.Convert(Encoding.GetEncoding("UTF-8"), Encoding.Default, bytes);
            return Encoding.UTF8.GetString(bytes);
        }

        // ------------------------提取正文并保存为文本文件------------------------
        static void testToTextFile()
        { 
            IntPtr infile = stringToUtf8Pointer(Encoding.UTF8.GetBytes("test\\graccvs文件正文提取接口.pdf"));
            IntPtr outfile = stringToUtf8Pointer(Encoding.UTF8.GetBytes("test\\out001.txt"));

            // 调用DLL函数得到文件正文
            Int32 code = toTextFile(infile, outfile);
            //TFE_OK为提取完成,其他code调用codeText返回相同错误
            if (code != (Int32)DllErrCode.TFE_OK)
            {
                // 方式1: 根据R值调用函数ErrText得到具体错误信息, 此方式速度快
                string err = codeText(code);
                Console.WriteLine("error from code: %s\n", err);

                // 方式2:调用DLL函数,得到具体错误信息, 此方式错误信息更加准确 
                IntPtr p = lastErr();
                string err2 = utf8PointerToString(p);
                Console.WriteLine("error from dll: %s\n", err2); 
            }
            else
            {
                Console.WriteLine("testToTextFile end\n");
            }
        }

        // ------------------------提取正文,返回字符串指针------------------------
        static void testToString()
        {
            byte[] bts = Encoding.UTF8.GetBytes("test\\简可信模板OCR识别工具帮助.docx");
            IntPtr infile = stringToUtf8Pointer(bts);
            IntPtr p = toString(infile); //返回UTF-8编码字符串
            try
            {
                string text = utf8PointerToString(p);
                Console.WriteLine("text=\n%s\n", text);
            }
            finally
            {
                freeString(p); // 务必调用freeString函数释放字符串内存
            }
        }

        // ------------------------HTTP提取正文并保存为文本文件------------------------
        static void testHttpToTextFile()
        {
            IntPtr rulPrt = stringToUtf8Pointer(Encoding.UTF8.GetBytes("https://www.gaya-soft.cn/dfs/v2/简可信模板OCR识别工具帮助.docx"));
            IntPtr extPrt = stringToUtf8Pointer(Encoding.UTF8.GetBytes(".docx"));
            IntPtr outFilePrt = stringToUtf8Pointer(Encoding.UTF8.GetBytes("test\\out002.txt"));
             
            // 调用DLL函数得到文件正文
            int timeout = 0; //超时设置,单位毫秒, 默认为0 
            int code = httpToTextFile(rulPrt, extPrt, outFilePrt, timeout, IntPtr.Zero);
            //TFE_OK为提取完成,其他code调用codeText返回相同错误
            if (code != (Int32)DllErrCode.TFE_OK)
            {
                string err = codeText(code);
                Console.WriteLine("error from code: %s\n", err); 
            }
            else
            {
                Console.WriteLine("testHttpToTextFile end\n");
            }
        }

        // ------------------------HTTP提取正文,返回字符串指针------------------------
        static void testHttpToString()
        {
            IntPtr rulPrt = stringToUtf8Pointer(Encoding.UTF8.GetBytes("https://www.gaya-soft.cn/dfs/v2/graccvs文件正文提取接口.pdf"));
            IntPtr extPrt = stringToUtf8Pointer(Encoding.UTF8.GetBytes(".pdf")); 
            string jsonParams = "{\"headers\":[{\"client_id\": \"g01x9\"}, {\"client_secret\": \"e23c89cc9fe\"}], \"cookies\":[{\"name\": \"ga\", \"value\": \"1020\", \"expires\":36000000, \"path\": \"/\"}]}";
            IntPtr jsonParamsPrt = stringToUtf8Pointer(Encoding.UTF8.GetBytes(jsonParams));
            int timeout = 60 * 1000; //超时设置,单位毫秒 

            IntPtr p = httpToString(rulPrt, extPrt, timeout, jsonParamsPrt); //返回UTF-8编码字符串
            try
            {
                string text = utf8PointerToString(p);
                Console.WriteLine("text=\n%s\n", text);
            }
            finally
            {
                freeString(p); // 务必调用freeString函数释放字符串内存
            }
        }
         
        // ---------------异步批量文件提取,适合多线程处理很多文件---------------
        // 文件提取任务 
        static void asyncAddTask()
        {
            // -----可以增加N个任务  
            IntPtr inFnPrt = stringToUtf8Pointer(Encoding.UTF8.GetBytes("test\\graccvs文件正文提取接口.pdf"));
            IntPtr outFnPrt = stringToUtf8Pointer(Encoding.UTF8.GetBytes("test\\asyncOut001.txt"));
            addTask(inFnPrt, outFnPrt); // 一个文件任务

            IntPtr inFnPrt2 = stringToUtf8Pointer(Encoding.UTF8.GetBytes("test\\Adobe Intro.ofd"));
            IntPtr outFnPrt2 = stringToUtf8Pointer(Encoding.UTF8.GetBytes("test\\asyncOut002.txt")); 
            addTask(inFnPrt2, outFnPrt2); // 一个文件任务
        }

        // Http文件提取任务 
        static void asyncAddHttpTask()
        {
            // 可以增加N个任务
            IntPtr rulPrt = stringToUtf8Pointer(Encoding.UTF8.GetBytes("https://www.gaya-soft.cn/dfs/v2/简可信模板OCR识别工具帮助.docx"));
            IntPtr extPrt = stringToUtf8Pointer(Encoding.UTF8.GetBytes(".docx"));
            IntPtr outFnPrt = stringToUtf8Pointer(Encoding.UTF8.GetBytes("test\\asyncOut003.txt"));  
            int timeout = 90 * 1000; //超时设置,单位毫秒, 默认为0
            addHttpTask(rulPrt, extPrt, outFnPrt, timeout, IntPtr.Zero);
        }

        // 方式1:开始任务,等待全部任务完成
        static void asyncRun1()
        {
            // 开始任务
            int r = asyncStart();
            if (r == 1)
            {
                asyncWait(); // 等待任务全部结束
                Console.WriteLine("方式1--任务完成\n"); 
            }
            else if (r == 2)
            {
                Console.WriteLine("免费版不支持此功能\n");  
            }
            else if (r == 3)
            {
                Console.WriteLine("没有可以执行的任务\n");  
            }
            else if (r == 4)
            {
                Console.WriteLine("当前任务未完成\n");
            }
        }


        // 方式2:判断执行情况,超时退出,主动结束任务
        static void asyncRun2()
        { 
            // 开始任务
            bool isOver = false;
            int r = asyncStart();
            if (r == 1)
            {
                System.DateTime start = new System.DateTime();
                // 5分钟后结束任务
                while (true)
                {
                    System.DateTime now = new System.DateTime();
                    TimeSpan ts = now - start;
                    // 5分钟后中断
                    if (ts.Minutes > 5 * 60)
                    {
                        break;
                    }
                    // 判断任务情况, =0 没开始, =1 正在处理中,=2 已中断, =99 处理完成
                    int x = asyncState();
                    if (x == 1)
                    {
                        Thread.Sleep(500);
                    }
                    else if (x == 99)
                    {
                        isOver = true; // 处理完成
                        break;
                    }
                    else
                    {
                        break;
                    }
                }
                //
                if (!isOver)
                {
                    asyncStop(); // 结束任务 
                }
                Console.WriteLine("方式2--任务完成\n");
            }
            else if (r == 2)
            {
                Console.WriteLine("免费版不支持此功能\n");
            }
            else if (r == 3)
            {
                Console.WriteLine("没有可以执行的任务\n");
            }
            else if (r == 4)
            {
                Console.WriteLine("当前任务未完成\n");
            }
        }

        static void asyncTest()
        { 
            asyncMaxProcs(8); // 同时运行8个任务
                              //
            asyncAddTask();  // 文件提取任务 
            asyncAddHttpTask(); // Http文件提取任务
                                      // 执行任务--方式1
            asyncRun1();

            // 执行任务--方式2
            asyncAddTask();
            asyncAddHttpTask();
            asyncRun2();
        }
        // ---------------异步批量文件提取,适合多线程处理很多文件---------------

        //
        static void Main(string[] args)
        {
            dll = new DllInvoke("graccvs64.dll"); //默认64位系统,32位DLL或者接口更新请到官网 
            if (dll == null)
            {
                Console.WriteLine("load dll error!");
                return;
            }

            if (!loadAllFun() )
            {
                Console.WriteLine("load dll error!");
                return;
            }
            //dll初始化函数
            IntPtr tempPath = stringToUtf8Pointer(Encoding.UTF8.GetBytes("test\\"));  
            load(tempPath);

            // 设置软件许可,免费版都为空
            IntPtr corpPrt = stringToUtf8Pointer(Encoding.UTF8.GetBytes("Beij Gaya"));
            IntPtr licTextPrt = stringToUtf8Pointer(Encoding.UTF8.GetBytes("")); 
            auth(corpPrt, licTextPrt);//企业版这里设置授权文本

            // 提取正文并保存为文本文件
            testToTextFile();
            // 提取正文,返回字符串指针
            testToString();
             
            // 提取HTTP提取正文, 并保存为文本文件
            testHttpToTextFile();
            // 提取HTTP提取正文, 返回字符串指针
            testHttpToString();

            // 异步批量文件提取测试
            asyncTest();

            //dll关闭DLL前执行此函数
            unload();

            Console.WriteLine("test over!");
            Console.ReadLine();
        }
    }
}


/*
  graccvs文件正文分析接口---北京盖亚软件有限公司版权所有
  -----------------------------------------------------------
  本接口为Lucene/CLucene, Elasticsearch, Sphinx等全文检索工具,OA, ERP, CRM等其他系统提供文件摘要及搜索前置服务。
  本接口提取文本速度快,质量高,跨平台,支持多任务并发。提供多种接口及示例。

  1: 接口提供多种操作系统动态链接库
  windows平台: (32bit和64bit)
    dll格式及GCC、VC、JAVA、C#、delphi调用示例 
    
  linux平台:支持(64bit)内核版本4.4及以上, 中标麒麟7.0.0(64bit)及以上
    注:内核版本(64bit)4.4以下也可能使用此接口, 具体以实际情况为准
    so格式文件及GCC、JAVA调用示例,其他语言完善中

  安卓平台:
    arr格式文件及Android Studio调用示例

  苹果ios平台:
    注:Mac os参考ios系统调用
    xcframework格式文件及xcode+objective-c调用示例

  2:接口现在可以提取的文件类型有(新增提取文件类型请关注官网):
    A: pdf文件
    B: office word文件 ".doc", ".odt", ".docx", ".dotm", ".docm"
    C: wps文档 ".wps"
    D: office excel文件 ".xls", ".xlsx", ".xlsm", ".xltm"
    E: wps表格 ".et"
    F: office powerPoint文件 ".ppt", ".pptx", ".potm", ".pptm", ".ppsm"
    G: wps演示 ".dps"
    H: 开放文档格式 ".ofd", 注:常见于“电子发票版式文件”
    I: 富文本类型 ".rtf"
    J: HTML页面文件  ".html", ".htm", ".mht", ".mhtml"
    K: 邮件格式文件 ".eml", 注:默认提取前5个附件
    L: 部分思维导图格式文件 ".emmx", "xmind", "gmind"
    M: UTF8编码, Unicode编码, Ansi编码的文本文件,
        ".txt", ".c", ".h", ".cpp", ".m", ".asp", ".aspx", ".cs", ".pas",
        ".php", ".vb", ".bas", ".js", ".css", ".java", ".jsp", ".go",
        ".pl", ".perl", ".ps", ".py", ".python", ".sql", ".rs", ".dart"
        注:可以在配置文件中增加纯文本文件后缀 
    N: 帮助文件 “*.chm",注:此格式仅限Windows平台
    O: 压缩文件 ".zip", 注:默认提取前5个文件

  3:返回字符串及文本文件为UTF-8编码

  4:提取最大文件默认为200M,配置文件可以设置此阀值

  5:企业版本提供异步多线程接口,可以同时批量处理多个文件

  6:接口详细文档参考 https://www.gaya-soft.cn/grhelp/

  7:接口提供 VC C++, GCC, C#, Java, Delphi, 安卓Java, 苹果C++调用接口示例
  示例下载地址 https://www.gaya-soft.cn/download/

  8:免费版本只提取40%到80%的正文文本内容,且有盖亚软件标识。
  软件注册请参考官网 https://www.gaya-soft.cn/grhelp/lic.html
*/

 类似资料: