65.9K
CodeProject 正在变化。 阅读更多。
Home

在 C# 中将 PDF 转换为文本

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.80/5 (132投票s)

2005 年 12 月 1 日

CPOL

3分钟阅读

viewsIcon

1990504

downloadIcon

31881

.NET 中使用 PDFBox 和 IKVM.NET(托管代码)解析 PDF 文件。

更新

2015 年 4 月 20 日: 文章和 Visual Studio 项目已更新,可与最新的 PDFBox 版本(1.8.9)配合使用。还可以下载包含所有依赖项的项目(解决依赖项问题可能有点棘手)。

2014 年 2 月 27 日: 本文最初介绍了使用 PDFBox 解析 PDF 文件。现已扩展,包含 IFilter 和 iTextSharp 的示例。

如何解析 PDF 文件

在 .NET 中提取 PDF 文件文本有几种主要方法

  • Microsoft IFilter 接口和 Adobe IFilter 实现。
  • iTextSharp
  • PDFBox

没有一种 PDF 解析解决方案是完美的。下面我们将讨论所有这些方法。

1. 使用 Adobe PDF IFilter 解析 PDF

要使用 IFilter 接口解析 PDF 文件,您需要以下条件

示例代码

using IFilter;

// ...

public static string ExtractTextFromPdf(string path) {
  return DefaultParser.Extract(path); 
} 

下载示例项目

如果您使用的是 Adobe Acrobat Reader 附带的 PDF IFilter,则需要将进程重命名为“filtdump.exe”,否则 IFilter 接口将返回 E_NOTIMPL 错误代码。更多信息请参阅 使用 IFilter 解析 PDF 文件 [squarepdf.net]。

缺点

  1. 使用不可靠的 COM 互操作来处理 IFilter 接口(IFilter COM 和 Adobe PDF IFilter 的组合尤其麻烦)。
  2. 在目标系统上单独安装 Adobe IFilter。如果您需要将索引解决方案分发给其他人,这可能会很麻烦。
  3. 对于最新版本的 Acrobat Reader 附带的 PDF IFilter,您必须使用“filtdump.exe”文件名来运行您的应用程序。

2. 使用 iTextSharp 解析 PDF

iTextSharpiText 的 .NET 移植版,iText 是一个用于 Java 的 PDF 操作库。它主要侧重于创建 PDF,而不是读取 PDF,但它也支持从 PDF 中提取文本。

示例代码

using iTextSharp.text.pdf;
using iTextSharp.text.pdf.parser;

// ...
 
public static string ExtractTextFromPdf(string path)
{
  using (PdfReader reader = new PdfReader(path))
  {
    StringBuilder text = new StringBuilder();

    for (int i = 1; i <= reader.NumberOfPages; i++)
    {
        text.Append(PdfTextExtractor.GetTextFromPage(reader, i));
    }

    return text.ToString();
  }
} 

致谢:会员 10364982

下载示例项目

您可以考虑使用 LocationTextExtractionStrategy 来获得更好的精度。

public static string ExtractTextFromPdf(string path)
{
  ITextExtractionStrategy its = new iTextSharp.text.pdf.parser.LocationTextExtractionStrategy();
  
  using (PdfReader reader = new PdfReader(path))
  {
      StringBuilder text = new StringBuilder();

      for (int i = 1; i <= reader.NumberOfPages; i++)
      {
          string thePage = PdfTextExtractor.GetTextFromPage(reader, i, its);
          string[] theLines = thePage.Split('\n');
          foreach (var theLine in theLines)
          {
              text.AppendLine(theLine);
          }
      }
      return text.ToString();
  }
}  

 

致谢:会员 10140900

iTextSharp 的缺点

  1. 许可,如果您对 AGPL 许可不满意

3. 使用 PDFBox 解析 PDF

PDFBox 是另一个 Java PDF 库。它也可以与原始的 Java Lucene 一起使用(参见 LucenePDFDocument)。

幸运的是,有一个使用 IKVM.NET 创建的 PDFBox 的 .NET 版本(只需下载 PDFBox 包)。

在 .NET 中使用 PDFBox 需要添加对以下文件的引用:

  • IKVM.OpenJDK.Core.dll
  • IKVM.OpenJDK.SwingAWT.dll
  • pdfbox-1.8.9.dll

并将以下文件复制到bin 目录:

  • commons-logging.dll
  • fontbox-1.8.9.dll
  • IKVM.OpenJDK.Text.dll
  • IKVM.OpenJDK.Util.dll
  • IKVM.Runtime.dll

使用 PDFBox 解析 PDF 非常简单

using org.apache.pdfbox.pdmodel;
using org.apache.pdfbox.util;

// ...

private static string ExtractTextFromPdf(string path)
{
  PDDocument doc = null;
  try {
    doc = PDDocument.load(path)
    PDFTextStripper stripper = new PDFTextStripper();
    return stripper.getText(doc);
  }
  finally {
    if (doc != null) {
      doc.close();
    }
  }
}  

下载示例项目

所需的程序集大小加起来将近 18 MB

  • IKVM.OpenJDK.Core.dll (4 MB)
  • IKVM.OpenJDK.SwingAWT.dll (6 MB)
  • pdfbox-1.8.9.dll (4 MB)
  • commons-logging.dll (82 kB)
  • fontbox-1.8.9.dll (180 kB)
  • IKVM.OpenJDK.Text.dll (800 kB)
  • IKVM.OpenJDK.Util.dll (2 MB)
  • IKVM.Runtime.dll (1 MB)

速度还不错:解析 美国版权法 PDF(5.1 MB)大约需要 13 秒。

感谢 bobrien100 提出的改进建议。

缺点

  1. IKVM.NET 依赖项 (18 MB)
  2. 速度(尤其是 IKVM.NET 的预热时间)

相关信息

  • 请参阅 SquarePDF.NET 上的这篇文章(包含未来更新)。

历史

  • 2015 年 4 月 20 日 - 更新为支持最新的 PDFBox 版本 (1.8.9)
  • 2014 年 11 月 27 日 - 更新为支持最新的 PDFBox 版本 (1.8.7)
  • 2014 年 3 月 10 日 - 添加了 IFilter 文件名限制,扩展了 iTextSharp 示例
  • 2014 年 2 月 27 日 - 添加了 IFilter 和 iTextSharp 的示例。
  • 2014 年 2 月 24 日 - 更新为支持最新的 PDFBox 版本 (1.8.4)
  • 2012 年 6 月 20 日 - 更新为支持最新的 PDFBox 版本 (1.7.0)
© . All rights reserved.