如何从C#中的MS office文档中提取文本

Eli*_*sie 35 c# text-extraction ms-office

我试图使用C#从MS Word(.doc,.docx),Excel和Powerpoint中提取文本(字符串).我在哪里可以找到一个免费且简单的.Net库来阅读MS Office文档?我尝试使用NPOI,但我没有得到关于如何使用NPOI的样本.

Kyl*_*leM 37

对于Microsoft Word 2007和Microsoft Word 2010(.docx)文件,您可以使用Open XML SDK.这段代码将打开一个文档并将其内容作为文本返回.对于任何试图使用正则表达式来解析Word文档内容的人来说,它尤其有用.要使用此解决方案,您需要引用DocumentFormat.OpenXml.dll,它是OpenXML SDK的一部分.

请参阅:http://msdn.microsoft.com/en-us/library/bb448854.aspx

 public static string TextFromWord(SPFile file)
    {
        const string wordmlNamespace = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";

        StringBuilder textBuilder = new StringBuilder();
        using (WordprocessingDocument wdDoc = WordprocessingDocument.Open(file.OpenBinaryStream(), false))
        {
            // Manage namespaces to perform XPath queries.  
            NameTable nt = new NameTable();
            XmlNamespaceManager nsManager = new XmlNamespaceManager(nt);
            nsManager.AddNamespace("w", wordmlNamespace);

            // Get the document part from the package.  
            // Load the XML in the document part into an XmlDocument instance.  
            XmlDocument xdoc = new XmlDocument(nt);
            xdoc.Load(wdDoc.MainDocumentPart.GetStream());

            XmlNodeList paragraphNodes = xdoc.SelectNodes("//w:p", nsManager);
            foreach (XmlNode paragraphNode in paragraphNodes)
            {
                XmlNodeList textNodes = paragraphNode.SelectNodes(".//w:t", nsManager);
                foreach (System.Xml.XmlNode textNode in textNodes)
                {
                    textBuilder.Append(textNode.InnerText);
                }
                textBuilder.Append(Environment.NewLine);
            }

        }
        return textBuilder.ToString();
    }
Run Code Online (Sandbox Code Playgroud)

  • @adrianbanks我觉得这个答案*目前*比接受的答案更好,因为接受的答案不适用于某些版本的Windows,因为IFilter是一个不赞成使用的界面.当然,在撰写adrian的帖子时并非如此. (5认同)
  • 我只是将SPFile更改为路径(字符串),而在open方法中我只使用了路径 - >它可以工作.解决方案非常简单明了. (3认同)
  • SPFile怎么样?您在函数中添加的参数属于此类型,我可以找到的有关Microsoft.Sharepoint.dll中的Microsoft.Sharepoint命名空间 - >并且此dll不容易找到.你引用什么来获得SPFile? (2认同)

adr*_*nks 26

使用PInvokes可以使用IFilter接口(在Windows上).许多常见文件类型的IFilter都随Windows一起安装(您可以使用工具浏览它们.您可以要求IFilter从文件中返回文本.有几组示例代码(是一个这样的示例).

  • 我使用了pInvoke,发现它很棒.要从任何文档中提取文本,我们所要做的就是确保在计算机上安装了适当的IFilter(或下载并安装).我喜欢这个清晰的示例表单代码项目,看看这个http://www.codeproject.com/KB/cs/IFilter.aspx for MS Office 2007这里是MS Office 2007过滤包http://www.microsoft. COM /下载/ details.aspx?FAMILYID = 60C92A37-719C-4077-B5C6-CAC34F4227CC&displaylang = EN (2认同)

Sep*_*Sep 15

Tika非常有用且易于从不同类型的文档中提取文本,包括Microsoft Office文件.

你可以使用这个项目,这是Kevin Miller制作的一件很好的艺术品 http://kevm.github.io/tikaondotnet/

只需添加此NuGet包 https://www.nuget.org/packages/TikaOnDotNet/

然后,这一行代码将完成魔术:

var text = new TikaOnDotNet.TextExtractor().Extract("fileName.docx  / pdf  / .... ").Text;
Run Code Online (Sandbox Code Playgroud)

  • 值得一提的是,它实际上是通过IKVM运行Apache Tika(java)的,而IKVM是Java的.net运行时,因此它不是轻量级的解决方案。(40MB的二进制文件,基本上是整个Java运行时) (3认同)

Jor*_*dan 8

让我稍微纠正KyleM给出的答案.我刚刚添加了两个额外节点的处理,这会影响结果:一个用"\ t"负责水平制表,另一个负责用于"\ v"的垂直制表.这是代码:

    public static string ReadAllTextFromDocx(FileInfo fileInfo)
    {
        StringBuilder stringBuilder;
        using(WordprocessingDocument wordprocessingDocument = WordprocessingDocument.Open(dataSourceFileInfo.FullName, false))
        {
            NameTable nameTable = new NameTable();
            XmlNamespaceManager xmlNamespaceManager = new XmlNamespaceManager(nameTable);
            xmlNamespaceManager.AddNamespace("w", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");

            string wordprocessingDocumentText;
            using(StreamReader streamReader = new StreamReader(wordprocessingDocument.MainDocumentPart.GetStream()))
            {
                wordprocessingDocumentText = streamReader.ReadToEnd();
            }

            stringBuilder = new StringBuilder(wordprocessingDocumentText.Length);

            XmlDocument xmlDocument = new XmlDocument(nameTable);
            xmlDocument.LoadXml(wordprocessingDocumentText);

            XmlNodeList paragraphNodes = xmlDocument.SelectNodes("//w:p", xmlNamespaceManager);
            foreach(XmlNode paragraphNode in paragraphNodes)
            {
                XmlNodeList textNodes = paragraphNode.SelectNodes(".//w:t | .//w:tab | .//w:br", xmlNamespaceManager);
                foreach(XmlNode textNode in textNodes)
                {
                    switch(textNode.Name)
                    {
                        case "w:t":
                            stringBuilder.Append(textNode.InnerText);
                            break;

                        case "w:tab":
                            stringBuilder.Append("\t");
                            break;

                        case "w:br":
                            stringBuilder.Append("\v");
                            break;
                    }
                }

                stringBuilder.Append(Environment.NewLine);
            }
        }

        return stringBuilder.ToString();
    }
Run Code Online (Sandbox Code Playgroud)


lxa*_*lxa 6

聚会有点晚了,但是 - 现在你不需要下载任何东西 - 所有东西都已经安装了 .NET :(只需确保添加对 System.IO.Compression 和 System.IO.Compression.FileSystem 的引用)

using System;
using System.Linq;
using System.Xml.Linq;
using System.Xml.XPath;
using System.Xml;
using System.Text;
using System.IO.Compression;

public static class DocxTextExtractor
{
    public static string Extract(string filename)
    {
        XmlNamespaceManager NsMgr = new XmlNamespaceManager(new NameTable());
        NsMgr.AddNamespace("w", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");

        using (var archive = ZipFile.OpenRead(filename))
        {
            return XDocument
                .Load(archive.GetEntry(@"word/document.xml").Open())
                .XPathSelectElements("//w:p", NsMgr)
                .Aggregate(new StringBuilder(), (sb, p) => p
                    .XPathSelectElements(".//w:t|.//w:tab|.//w:br", NsMgr)
                    .Select(e => { switch (e.Name.LocalName) { case "br": return "\v"; case "tab": return "\t"; } return e.Value; })
                    .Aggregate(sb, (sb1, v) => sb1.Append(v)))
                .ToString();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


Chr*_*ris 6

使用Microsoft Office Interop。它是免费的和光滑的。在这里,我是如何从文档中提取所有单词的。

    using Microsoft.Office.Interop.Word;

   //Create Doc
    string docPath = @"C:\docLocation.doc";
    Application app = new Application();
    Document doc = app.Documents.Open(docPath);

    //Get all words
    string allWords = doc.Content.Text;
    doc.Close();
    app.Quit();
Run Code Online (Sandbox Code Playgroud)

然后用这些词做任何您想做的。

  • _这是免费的--是否不要求您安装Word? (2认同)
  • @Chris:除了 Matt Burland 的 catch22 之外,我如何在 Linux 服务器上运行它?;) (2认同)