利用Lucene.net对附件做搜索

  1. #region 利用com组件读取office
  2.     /// <summary>
  3.     /// 判断文件是否存在
  4.     /// </summary>
  5.     /// <param name="pFileName"></param>
  6.     private void IsExists(string pFileName) {
  7.         if (!File.Exists(pFileName)) {
  8.             throw new ApplicationException("指定目录下的无该文件");
  9.         }
  10.     }
  11.     //获得word文件的文本内容
  12.     public string Doc2Text(string docFileName) {
  13.         IsExists(docFileName);
  14.         //实例化COM
  15.         Word.ApplicationClass wordApp = new Word.ApplicationClass();
  16.         object fileobj = docFileName;
  17.         object nullobj = System.Reflection.Missing.Value;
  18.         //打开指定文件(不同版本的COM参数个数有差异,一般而言除第一个外都用nullobj就行了)
  19.         Word.Document doc = wordApp.Documents.Open(ref fileobj, ref nullobj, ref nullobj,
  20.             ref nullobj, ref nullobj, ref nullobj,
  21.             ref nullobj, ref nullobj, ref nullobj,
  22.             ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj
  23.             );
  24.         //取得doc文件中的文本
  25.         string outText = doc.Content.Text;
  26.         //关闭文件
  27.         doc.Close(ref nullobj, ref nullobj, ref nullobj);
  28.         //关闭COM,关闭word程序
  29.         wordApp.Quit(ref nullobj, ref nullobj, ref nullobj);
  30.         GC.Collect();
  31.         //返回
  32.         return outText;
  33.     }
  34.     //获得excel文件的文本内容
  35.     public string Xls2Text(string xlsFileName) {
  36.         IsExists(xlsFileName);
  37.         Excel.Application xlsApp = new Excel.ApplicationClass();
  38.         object nullobj = System.Reflection.Missing.Value;
  39.         //打开Excel文档
  40.         Excel.Workbook excel = xlsApp.Workbooks.Open(xlsFileName, nullobj,
  41.                     nullobj, nullobj, nullobj,
  42.                     nullobj, nullobj, nullobj,
  43.                     nullobj, nullobj, nullobj,
  44.                     nullobj, nullobj, nullobj,
  45.                     nullobj);
  46.         //遍历Excel工作表
  47.         Excel.Worksheet ews = null;
  48.         StringBuilder builder = new StringBuilder();
  49.         try
  50.         {
  51.             for (int k = 1; k <= excel.Worksheets.Count; k++)
  52.             {
  53.                 ews = (Excel.Worksheet)excel.Worksheets[k];
  54.                 //builder.Append(((Excel.Range)ews.UsedRange).Text);
  55.                 if (ews.UsedRange.Value2 != null)
  56.                 {
  57.                     for (int i = 1; i <= ews.UsedRange.Cells.Rows.Count; i++)
  58.                     {
  59.                         for (int j = 1; j <= ews.UsedRange.Cells.Columns.Count; j++)
  60.                         {
  61.                             if (((object[,])(ews.UsedRange.Value2))[i, j] != null)
  62.                             {
  63.                                 builder.Append(((object[,])(ews.UsedRange.Value2))[i, j]).Append("|");
  64.                             }
  65.                         }
  66.                     }
  67.                 }
  68.             }
  69.         }
  70.         catch (Exception ex)
  71.         {
  72.             throw ex;
  73.         }
  74.         finally
  75.         {
  76.             excel.Close(nullobj, nullobj, nullobj);
  77.             xlsApp.Quit();
  78.             GC.Collect();
  79.         }
  80.         return builder.ToString();
  81.     }
  82.     //获得PPT文件的文本内容
  83.     public string Ppt2Text(string pptFileName) {
  84.         IsExists(pptFileName);
  85.         PowerPoint.Application pptApp = new PowerPoint.ApplicationClass();
  86.         object nullobj = System.Reflection.Missing.Value;
  87.         PowerPoint.Presentation ppt = pptApp.Presentations.Open(pptFileName,
  88.                 Microsoft.Office.Core.MsoTriState.msoTrue,
  89.                 Microsoft.Office.Core.MsoTriState.msoFalse,
  90.                 Microsoft.Office.Core.MsoTriState.msoFalse);
  91.         StringBuilder builder = new StringBuilder();
  92.         try
  93.         {
  94.             foreach (PowerPoint.Slide slide in ppt.Slides)
  95.             {
  96.                 foreach (PowerPoint.Shape shape in slide.Shapes)
  97.                 {
  98.                     if (shape.TextFrame.HasText == Microsoft.Office.Core.MsoTriState.msoTrue)
  99.                     {
  100.                         builder.Append(shape.TextFrame.TextRange.Text);
  101.                     }
  102.                  
  103.                 }
  104.             }
  105.         }
  106.         catch (Exception ex)
  107.         {
  108.             throw ex;
  109.         }
  110.         finally {
  111.             ppt.Close();
  112.             pptApp.Quit();
  113.             GC.Collect();
  114.         }
  115.         return builder.ToString();
  116.     }
  117.     #endregion
 
    最近研究了个全文搜索的,Lucene.net,很有名的开源组件(有Java版本)。其实谈不上研究,就是以前客户有个需要,要能搜索上传文件(如 word Excel Txt 等等),项目中这些附件都存在一个image字段中的,一直没有办法来搜索,本文就讲一下如何利用Lucene.net对附件做搜索功能,并且利用com 组件来读取office内容。
介绍一下Lucene.net的使用,使用了Lucene.Net.dll2.1   Highlighter.Net.dll 2.0(高亮)  Lucene.Net.Analysis.Cn.dll 1.3(划词引擎)
1 添加索引


  1. Code
  2.  /// <summary>
  3.     /// 添加索引
  4.     /// </summary>
  5.     /// <param name="file">索引实体Files</param>
  6.     public void AddIndex(Files file) {
  7.         IndexWriter writer;
  8.         if (IndexReader.IndexExists(GetIndexPath)) {
  9.             //非第一次递加
  10.             writer = new IndexWriter(GetIndexPath, this.Analyzer, false);
  11.         }
  12.         else {
  13.             //第一次创建
  14.             writer = new IndexWriter(GetIndexPath, this.Analyzer, true);
  15.         }
  16.         Document doc = new Document();
  17.         doc.Add(new Field("FileId", file.ID, Field.Store.YES, Field.Index.UN_TOKENIZED));//Field.Index.UN_TOKENIZED 类似把这字段作为主键
  18.         doc.Add(new Field("Title", file.Title, Field.Store.YES, Field.Index.TOKENIZED));
  19.         switch (file.FileType) {
  20.             case FileType.Txt:
  21.                 doc.Add(new Field("File"new StreamReader(file.Stream, System.Text.Encoding.Default)));
  22.                 break;
  23.             case FileType.Word:
  24.                 doc.Add(new Field("File", Doc2Text(file.FileName), Field.Store.YES, Field.Index.TOKENIZED));
  25.                 break;
  26.             case FileType.Excel:
  27.                 doc.Add(new Field("File", Xls2Text(file.FileName), Field.Store.YES, Field.Index.TOKENIZED));
  28.                 break;
  29.             case FileType.Ppt:
  30.                 doc.Add(new Field("File", Ppt2Text(file.FileName), Field.Store.YES, Field.Index.TOKENIZED));
  31.                 break;
  32.             case FileType.Mht:
  33.                 doc.Add(new Field("File", Doc2Text(file.FileName), Field.Store.YES, Field.Index.TOKENIZED));
  34.                 break;
  35.             case FileType.Htm:
  36.                 doc.Add(new Field("File"new StreamReader(file.Stream, System.Text.Encoding.Default)));
  37.                 break;
  38.             default:
  39.                 break;
  40.         }
  41.         writer.AddDocument(doc);
  42.         writer.Optimize();
  43.         writer.Close();
  44.     }


   其中,把id 的index设为Field.Index.UN_TOKENIZED,差不多就是id做为主键,后面删除索引的时候,直接删除这个id就行

   switch (file.FileType)就是根据附件类型,解析读取内容

 

 2 搜索

  1. Code
  2.  /// <summary>
  3.     /// 搜索
  4.     /// </summary>
  5.     /// <param name="pSearchStr">查询字符</param>
  6.     /// <returns>返回结果集</returns>
  7.     public DataTable Search(string pSearchStr) {
  8.         if (!string.IsNullOrEmpty(pSearchStr)) {
  9.             IndexSearcher searcher = new IndexSearcher(this.GetIndexPath);
  10.             //单字段搜索
  11.             //QueryParser parser = new QueryParser("title", this.Analyzer);
  12.             //Query query = parser.Parse(this.TextBox2.Text.Trim());

  13.             //多字段搜索
  14.             Query query = MultiFieldQueryParser.Parse(new string[] { pSearchStr, pSearchStr } , new string[] { "Title""File" }, this.Analyzer);

  15.             Hits h = searcher.Search(query);
  16.             Document doc;

  17.             //高亮显示
  18.             SimpleHTMLFormatter simpleHTMLFormatter = new SimpleHTMLFormatter("<font color=/"red/">""</font>");
  19.             Highlighter highlighter = new Highlighter(simpleHTMLFormatter, new QueryScorer(query));
  20.             //关键内容显示大小设置 
  21.             //highlighter.SetTextFragmenter(new SimpleFragmenter(400));

  22.             DataTable dt = new DataTable();
  23.             dt.Columns.Add("Id");//序号
  24.             dt.Columns.Add("FileId");//记录ID
  25.             dt.Columns.Add("Title");//标题

  26.             for (int i = 0; i < h.Length(); i++) {
  27.                 doc = h.Doc(i);
  28.                 #region 下载
  29.                 //try {
  30.                 //    //string strFile=HttpUtility.UrlEncode( myTable.Rows[0]["FileName"].ToString(), System.Text.Encoding.GetEncoding("GB2312")).Replace("+"," ");
  31.                 //    string strFile = HttpUtility.UrlEncode(doc.GetField("title").StringValue(), System.Text.Encoding.UTF8);
  32.                 //    Response.AddHeader("Content-Disposition", "attachment;filename=" + strFile);
  33.                 //    Response.ContentType = ("application/unknown");
  34.                 //    byte[] myByte = doc.GetField("file").BinaryValue();
  35.                 //    Response.BinaryWrite(myByte);
  36.                 //    Response.End();
  37.                 //}
  38.                 //catch { }
  39.                 #endregion

  40.                 string title = doc.Get("Title");
  41.                 //取出高亮显示内容
  42.                 TokenStream tokenStream = (this.Analyzer).TokenStream("Title"new StringReader(title));
  43.                 string newTitle = highlighter.GetBestFragments(tokenStream, title, 5, "");
  44.                 if (!string.IsNullOrEmpty(newTitle)) {
  45.                     title = newTitle;
  46.                 }

  47.                 this.AddRow(dt, i + 1, doc.Get("FileId"), title);

  48.             }
  49.             searcher.Close();
  50.             return dt;
  51.         }
  52.         return null;
  53.     }

    现在只对标题(title)和内容(file)做了索引,所以只对这两个字段进行搜索. 最后,返回一个DataTable,包括FileID(记录ID,以便下载附件)和Title(标题). 其中对搜索结果使用了高亮显示Highlighter.

 

 3 删除索引

 

  1.     /// <summary>
  2.     /// 删除索引
  3.     /// </summary>
  4.     /// <param name="pID"></param>
  5.     public void Delete(string pID) {
  6.         IndexReader reader = IndexReader.Open(GetIndexPath);
  7.         Term aTerm = new Term("FileId", pID);
  8.         reader.DeleteDocuments(aTerm);
  9.         reader.Close();//必须,真正删除
  10.     }
   先创建个Term,然后用IndexReader删除

 

 4 其他一些辅助属性


  1. #region 属性

  2.     string INDEX_STORE_PATH = "index";
  3.     /// <summary>
  4.     /// 获取/设置index目录
  5.     /// </summary>
  6.     public string IndexPath {
  7.         get {
  8.             return INDEX_STORE_PATH;
  9.         }
  10.         set {
  11.             INDEX_STORE_PATH = value;
  12.         }
  13.     }

  14.     /// <summary>
  15.     /// 换成物理地址
  16.     /// </summary>
  17.     private string GetIndexPath {
  18.         get {
  19.             return HttpContext.Current.Server.MapPath(INDEX_STORE_PATH);
  20.         }
  21.     }

  22.     Analyzer _analyzer = new ChineseAnalyzer();
  23.     /// <summary>
  24.     /// 获取/设置分析器
  25.     /// </summary>
  26.     public Analyzer Analyzer {
  27.         get {
  28.             return _analyzer;
  29.         }
  30.         set {
  31.             _analyzer = value;
  32.         }
  33.     }
  34.     #endregion

5 通过com组件读取office文档内容


  1. #region 利用com组件读取office

  2.     /// <summary>
  3.     /// 判断文件是否存在
  4.     /// </summary>
  5.     /// <param name="pFileName"></param>
  6.     private void IsExists(string pFileName) {
  7.         if (!File.Exists(pFileName)) {
  8.             throw new ApplicationException("指定目录下的无该文件");
  9.         }
  10.     }

  11.     //获得word文件的文本内容
  12.     public string Doc2Text(string docFileName) {
  13.         IsExists(docFileName);
  14.         //实例化COM
  15.         Word.ApplicationClass wordApp = new Word.ApplicationClass();
  16.         object fileobj = docFileName;
  17.         object nullobj = System.Reflection.Missing.Value;
  18.         //打开指定文件(不同版本的COM参数个数有差异,一般而言除第一个外都用nullobj就行了)
  19.         Word.Document doc = wordApp.Documents.Open(ref fileobj, ref nullobj, ref nullobj,
  20.             ref nullobj, ref nullobj, ref nullobj,
  21.             ref nullobj, ref nullobj, ref nullobj,
  22.             ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj
  23.             );

  24.         //取得doc文件中的文本
  25.         string outText = doc.Content.Text;
  26.         //关闭文件
  27.         doc.Close(ref nullobj, ref nullobj, ref nullobj);
  28.         //关闭COM,关闭word程序
  29.         wordApp.Quit(ref nullobj, ref nullobj, ref nullobj);
  30.         GC.Collect();
  31.         //返回
  32.         return outText;
  33.     }

  34.     //获得excel文件的文本内容
  35.     public string Xls2Text(string xlsFileName) {
  36.         IsExists(xlsFileName);
  37.         Excel.Application xlsApp = new Excel.ApplicationClass();
  38.         object nullobj = System.Reflection.Missing.Value;
  39.         //打开Excel文档
  40.         Excel.Workbook excel = xlsApp.Workbooks.Open(xlsFileName, nullobj,
  41.                     nullobj, nullobj, nullobj,
  42.                     nullobj, nullobj, nullobj,
  43.                     nullobj, nullobj, nullobj,
  44.                     nullobj, nullobj, nullobj,
  45.                     nullobj);

  46.         //遍历Excel工作表
  47.         Excel.Worksheet ews = null;
  48.         StringBuilder builder = new StringBuilder();
  49.         try
  50.         {
  51.             for (int k = 1; k <= excel.Worksheets.Count; k++)
  52.             {
  53.                 ews = (Excel.Worksheet)excel.Worksheets[k];
  54.                 //builder.Append(((Excel.Range)ews.UsedRange).Text);
  55.                 if (ews.UsedRange.Value2 != null)
  56.                 {
  57.                     for (int i = 1; i <= ews.UsedRange.Cells.Rows.Count; i++)
  58.                     {
  59.                         for (int j = 1; j <= ews.UsedRange.Cells.Columns.Count; j++)
  60.                         {
  61.                             if (((object[,])(ews.UsedRange.Value2))[i, j] != null)
  62.                             {
  63.                                 builder.Append(((object[,])(ews.UsedRange.Value2))[i, j]).Append("|");
  64.                             }

  65.                         }
  66.                     }
  67.                 }

  68.             }
  69.         }
  70.         catch (Exception ex)
  71.         {

  72.             throw ex;
  73.         }
  74.         finally
  75.         {
  76.             excel.Close(nullobj, nullobj, nullobj);
  77.             xlsApp.Quit();
  78.             GC.Collect();
  79.         }
  80.         return builder.ToString();
  81.     }

  82.     //获得PPT文件的文本内容
  83.     public string Ppt2Text(string pptFileName) {
  84.         IsExists(pptFileName);
  85.         PowerPoint.Application pptApp = new PowerPoint.ApplicationClass();
  86.         object nullobj = System.Reflection.Missing.Value;
  87.         PowerPoint.Presentation ppt = pptApp.Presentations.Open(pptFileName,
  88.                 Microsoft.Office.Core.MsoTriState.msoTrue,
  89.                 Microsoft.Office.Core.MsoTriState.msoFalse,
  90.                 Microsoft.Office.Core.MsoTriState.msoFalse);
  91.         StringBuilder builder = new StringBuilder();
  92.         try
  93.         {
  94.             foreach (PowerPoint.Slide slide in ppt.Slides)
  95.             {
  96.                 foreach (PowerPoint.Shape shape in slide.Shapes)
  97.                 {
  98.                     if (shape.TextFrame.HasText == Microsoft.Office.Core.MsoTriState.msoTrue)
  99.                     {
  100.                         builder.Append(shape.TextFrame.TextRange.Text);
  101.                     }
  102.                  
  103.                 }
  104.             }
  105.         }
  106.         catch (Exception ex)
  107.         {

  108.             throw ex;
  109.         }
  110.         finally {
  111.             ppt.Close();
  112.             pptApp.Quit();
  113.             GC.Collect();
  114.         }


  115.         return builder.ToString();
  116.     }

  117.     #endregion
此内容写得比较详细,为转贴吧,我在自已用的时候已民写成vb.net

格式,并优化一下,可以相关文章里有代码


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值