快速搜索 Word 2007 文档






4.50/5 (4投票s)
2006 年 11 月 15 日
4分钟阅读

47747

656
如何使用 Office 2007 OpenXML 文件格式进行快速搜索。
引言
Office 2007 引入了 OpenXML 文件格式。这意味着 Word、Excel 和 PowerPoint 文件只是压缩文件,或者可以说它们是几个预定义 XML 文件的集合。所有 Word、Excel 和 PowerPoint 文件的元数据和数据都定义在 XML 文件中。
有关 OpenXML 文件的更多详细信息,请访问此处。您可以在这里找到所有支持 OpenXML 文件格式的 Office 2007 应用程序的文件格式的描述和详细信息。所有数据都以 XML 格式存储,我利用了这个关键因素来搜索文件中的文本。
在我的示例代码中,您可以看到我遍历所有 .docx 文件,并使用 Package
对象打开每个文件,该对象可以在 System.IO.Packaging
命名空间中找到。
System.IO.Packaging
命名空间是 .NET Framework 3.0 的一部分。您可以从此处下载。我还使用了后台线程来处理 GUI 操作,例如更新进度条和其他控件。
文件格式
在这里,我们将简要讨论 .docx 文件格式。只需创建一个 .docx 文件,然后在其中键入一些单词或文本。现在保存文件,然后转到 Windows 资源管理器,将文件重命名为 .zip 扩展名(Word、Excel、PowerPoint 文件实际上是 zip 文件)。现在双击打开它。它将显示文件夹结构和其中的文件。
现在导航到 Word 文件夹并打开 document.xml 文件。您可以看到您在 Word 文件中输入的所有数据都在这里。另一件重要的事情是所有数据都包含在 <w:t>
标签中。这是我们将用于在每个文件中搜索的键。
Using the Code
下载代码并打开解决方案。转到 Docfileparse.cs。在此类中,您会找到一个名为 Docfileparse
的类,它有一个构造函数。
/// <summary>
/// Constructor
/// </summary>
/// <param name="_filename">The Name of file to parse</param>
/// <param name="_searchtext">The text we need to search</param>
/// <param name="iscasesenstive">is the search case sensitive</param>
/// <param name="_matchword">Do we need to match the exact word</param>
public Docfileparse(string _filename,string _searchtext,bool iscasesenstive,
bool _matchword)
{
filename = _filename;
searchtext = _searchtext;
casesenstive = iscasesenstive;
if (casesenstive == false)
searchtext = searchtext.ToLower();
matchword = _matchword;
}
我们正在尝试支持另外两种搜索类型。它们是:
- 区分大小写
- 匹配整个单词
我们将这两个参数传递给构造函数,让类知道我们要执行哪种类型的搜索。
在区分大小写的搜索中,我们搜索精确的文本。如果不是区分大小写,则我们将所有数据转换为小写进行搜索。
在第二种情况下,如果用户想搜索整个单词,那么我们将主字符串拆分成单词,然后逐个匹配用户想要搜索的字符串与每个单词。
GUI 主窗体在后台线程方法 ThreadProc
中创建了 Docparsefile
类的对象。
public void ThreadProc()
{
DirectoryInfo df=new DirectoryInfo(textBox1.Text);
int i = 0;
foreach (FileInfo f in df.GetFiles("*.docx"))
{
if (progressBar1.Value < progressBar1.Maximum)
{
MethodInvoker mi = new MethodInvoker(this.UpdateProgress);
this.BeginInvoke(mi);
}
else
{
MethodInvoker mi = new MethodInvoker(this.resetProgress);
this.BeginInvoke(mi);
}
i++;
//Creates object of DocParseFile and pass file path and other
//parameter values
Docfileparse docparser = new Docfileparse
(f.FullName,textBox2.Text,checkBox1.Checked,checkBox2.Checked);
string _message="";
//Call SearchText method on the object that returns true or false
if (docparser.searchText(ref _message) == true)
{
SetlistboxText(f.FullName);
}
docparser = null;
SetlabelText(i);
}
MethodInvoker mdone = new MethodInvoker(this.Processdone);
IAsyncResult ia= this.BeginInvoke(mdone);
}
这段代码看起来有点复杂,因为我试图提供一个运行良好的应用程序。否则,如果您想将此搜索功能插入到任何其他地方,DocParseFile.cs 就足够了。
代码分步讲解
在 Docparsefile
类中,用户创建 DocParseFile
类的对象并调用构造函数,该构造函数初始化类中的参数。当用户调用 searchText
方法时,它会执行以下步骤:
打开 Word (.docx) 文件 package
private bool openpack()
{
try
{
filepack = Package.Open(filename, FileMode.Open,
FileAccess.Read);
return true;
}
catch (Exception )
{
return false;
}
}
导航到 Package
中的 document.xml 文件并加载该 XMLDocument
。
private XmlDocument loadXmlDoc()
{
try
{
XmlDocument xmdoc=new XmlDocument();
Uri pathtodoc = new Uri("/word/document.xml", UriKind.Relative);
PackagePart newPart = filepack.GetPart(pathtodoc);
xmdoc.Load(newPart.GetStream(FileMode.Open, FileAccess.Read));
return xmdoc;
}
catch (Exception)
{
return null;
}
}
现在,通过在 ClosePackage
方法中调用 package.close()
方法来关闭 package
。现在我们得到了存储所有数据的 Xmldocument
,因此我们不再需要保持 package
打开。现在我们将在此 Xmldocument
中搜索数据。如果找到,searchText
方法将返回 true
,否则将返回 false
。下一步是在 XmlDocument
中搜索文本。如我在文件格式部分所述,所有数据都存储在 <w:t>
标签中,因此我们将查询 Xmldocument
并获取该标签的所有元素,然后我们将遍历每个标签以检查 InnerText
并匹配文本。
private bool IstextinFile(XmlDocument xmldocument)
{
XmlNodeList textNodes = xmldocument.GetElementsByTagName("w:t");
string text = "";
foreach (XmlNode xmnode in textNodes)
{
text = xmnode.InnerText;
if (casesenstive == false)
text = text.ToLower();
if (matchword == false)
{
if (text.IndexOf(searchtext) >= 0)
return true;
}
else
{
char[] separator ={ ' ' };
string[] _wrods = text.Split(separator);
foreach (string wordc in _wrods)
{
if (wordc.Equals(searchtext) == true)
return true;
}
}
}
return false;
}
就这样,我们完成了。在 UI 中,我添加了一些很酷的功能,例如,搜索后,您可以右键单击文件名并在 Word 中打开,或者您可以双击打开文件。目前,我已经为 Word 创建了这个示例,并且我计划将其扩展到 Excel 和 PowerPoint。
您可以进一步探索,以便为组织提供一个在线工具来搜索文档/演示文稿。此外,我认为这种搜索比 Windows 搜索更快。我已经用 60 多个文件进行了测试,它的运行速度比 Windows 搜索快。
如果您遗漏了什么,或者您认为我可以进一步改进,请提供您的反馈。