如何使用 Spire.PDF 从 PDF 中提取文本?

如何使用 Spire.PDF 从 PDF 中提取文本?

在处理PDF文档时,经常需要从中提取文本内容用于数据分析或搜索入库。使用Spire.PDF for .NET,只需几行C#代码即可精准提取PDF中的文本,支持保留格式和批量处理,轻松解决文本提取需求。

为什么选择 Spire.PDF 进行文本提取?

Spire.PDF 是由 e-iceblue 公司开发的一款专业的 PDF 组件,专为 .NET 平台设计,支持在 C#、VB.NET 等语言中创建、读取、编辑、转换和打印 PDF 文档。在文本提取方面,Spire.PDF 展现出诸多独特优势:

  • 广泛的兼容性: Spire.PDF 支持各种 PDF 版本,包括加密和受保护的 PDF 文档,确保了在不同场景下的通用性。
  • 灵活的提取模式: 它不仅支持提取整页文本,还能按指定区域、按行、甚至按特定格式(如文本元素的位置、大小、字体、颜色)进行精细化提取,满足多样化的需求。
  • 出色的复杂布局处理能力: 面对表格、多列布局、图片环绕文本等复杂页面结构,Spire.PDF 能够更好地识别和还原文本的逻辑顺序,减少乱码和布局错乱的发生。
  • 多语言支持: 对于包含中文、日文、韩文等多种语言的 PDF 文档,Spire.PDF 也能提供良好的支持,确保字符编码的正确性。
  • 易于使用与高性能: API 设计直观简洁,学习成本低。同时,其底层优化确保了在处理大型 PDF 文件时依然能保持高效的性能。
  • (对比其他库): 相较于一些开源库如 iTextSharp,Spire.PDF 在商业支持、API 易用性以及对复杂 PDF 的处理能力上往往更具优势;与 PDFium 等底层库相比,Spire.PDF 提供了更高级别的抽象,减少了开发者的工作量。

Spire.PDF 文本提取实战:基础用法

现在,让我们通过具体的 C# 代码示例,深入了解如何使用 Spire.PDF 进行文本提取。

2.1 环境准备与库安装

首先,你需要在你的 .NET 项目中安装 Spire.PDF 库。最简单的方式是通过 NuGet 包管理器:

复制代码
Install-Package Spire.PDF

或者在 Visual Studio 的 NuGet 包管理器中搜索 "Spire.PDF" 并安装。

2.2 提取整页文本

这是最常见的文本提取场景,即提取 PDF 文档中每一页的所有文本内容。

csharp 复制代码
using Spire.Pdf;
using System.Text; // 引入 StringBuilder 命名空间

class Program
{
    static void Main(string[] args)
    {
        // 1. 加载 PDF 文档
        PdfDocument doc = new PdfDocument();
        doc.Load("Sample.pdf"); // 替换为你的 PDF 文件路径

        StringBuilder fullText = new StringBuilder();

        // 2. 遍历文档中的每一页
        foreach (PdfPageBase page in doc.Pages)
        {
            // 3. 提取当前页的所有文本
            string textOnPage = page.ExtractText();
            fullText.AppendLine(textOnPage);

            // 可选:打印每页文本
            // Console.WriteLine($"--- Page {page.PageIndex + 1} ---");
            // Console.WriteLine(textOnPage);
        }

        // 4. 将所有文本保存到文件或进行其他处理
        System.IO.File.WriteAllText("ExtractedFullText.txt", fullText.ToString());
        Console.WriteLine("文本已成功提取并保存到 ExtractedFullText.txt");

        // 5. 释放资源
        doc.Close();
    }
}

代码解析:

  • PdfDocument doc = new PdfDocument(); doc.Load("Sample.pdf"); 用于加载目标 PDF 文档。
  • foreach (PdfPageBase page in doc.Pages) 遍历文档中的所有页面。
  • page.ExtractText() 是核心方法,用于提取当前页面的所有文本内容。
  • StringBuilder 用于高效地拼接所有页面的文本。
  • doc.Close() 释放文档资源,这是一个良好的编程习惯。

2.3 提取指定区域文本

有时我们只需要 PDF 页面中某个特定区域的文本,例如一个表格或者某个数据块。Spire.PDF 允许我们通过定义一个矩形区域来精确提取文本。

csharp 复制代码
using Spire.Pdf;
using Spire.Pdf.Graphics; // 引入 RectangleF 命名空间
using Spire.Pdf.Texts; // 引入 PdfTextExtractor 命名空间
using System.Drawing; // 引入 Color 命名空间

class Program
{
    static void Main(string[] args)
    {
        // 1. 加载 PDF 文档
        PdfDocument doc = new PdfDocument();
        doc.Load("Sample.pdf"); 

        // 2. 获取第一页(或其他指定页)
        PdfPageBase page = doc.Pages[0];

        // 3. 定义要提取文本的矩形区域
        // RectangleF(x, y, width, height)
        // x, y 是矩形左上角的坐标,width, height 是矩形的宽度和高度。
        // PDF 坐标系的原点通常在左下角或左上角,具体取决于库的实现。
        // Spire.PDF 默认是左上角为 (0,0),Y轴向下。
        RectangleF extractArea = new RectangleF(80, 180, 500, 200); // 示例坐标和尺寸

        // 4. 创建文本提取选项
        PdfTextExtractOptions options = new PdfTextExtractOptions();
        options.ExtractArea = extractArea;

        // 5. 使用 PdfTextExtractor 提取指定区域文本
        PdfTextExtractor extractor = new PdfTextExtractor(page);
        string extractedText = extractor.ExtractText(options);

        Console.WriteLine($"从指定区域提取的文本:\n{extractedText}");

        // 6. 释放资源
        doc.Close();
    }
}

代码解析:

  • RectangleF extractArea = new RectangleF(80, 180, 500, 200); 定义了一个浮点型矩形,用于指定提取区域。xy 是相对于页面左上角的偏移量,widthheight 是区域的尺寸。
  • PdfTextExtractOptions options = new PdfTextExtractOptions(); options.ExtractArea = extractArea; 将定义的区域作为提取选项。
  • PdfTextExtractor extractor = new PdfTextExtractor(page); 创建一个页面文本提取器实例。
  • extractor.ExtractText(options); 使用带有区域选项的提取器来获取文本。

2.4 提取特定格式文本

Spire.PDF 还提供了更高级的文本提取能力,例如提取被高亮(highlight)的文本。这在处理批注和审阅过的文档时非常有用。

csharp 复制代码
using Spire.Pdf;
using Spire.Pdf.Annotations; // 引入 PdfTextMarkupAnnotationWidget 命名空间
using Spire.Pdf.Graphics;
using Spire.Pdf.Texts;
using System.Drawing;
using System.Text;

class Program
{
    static void Main(string[] args)
    {
        PdfDocument doc = new PdfDocument();
        doc.Load("SampleWithHighlight.pdf"); // 替换为包含高亮文本的 PDF 文件

        PdfPageBase page = doc.Pages[0]; // 获取第一页
        StringBuilder stringBuilder = new StringBuilder();
        PdfTextExtractor pdfTextExtractor = new PdfTextExtractor(page);

        // 遍历页面上的所有批注
        for (int i = 0; i < page.Annotations.Count; i++)
        {
            if (page.Annotations[i] is PdfTextMarkupAnnotationWidget textMarkupAnnotation)
            {
                // 如果是文本标记批注(如高亮、删除线等)
                // 获取高亮区域的边界
                PdfTextExtractOptions pdfTextExtractOptions = new PdfTextExtractOptions();
                pdfTextExtractOptions.ExtractArea = textMarkupAnnotation.Bounds;
                
                // 提取高亮区域的文本
                string highlightedText = pdfTextExtractor.ExtractText(pdfTextExtractOptions);
                stringBuilder.AppendLine(highlightedText);

                // 可选:获取高亮颜色
                Color color = textMarkupAnnotation.TextMarkupColor;
                Console.WriteLine($"检测到高亮文本: '{highlightedText}' (颜色: {color})");
            }
        }
        
        System.IO.File.WriteAllText("ExtractedHighlightedText.txt", stringBuilder.ToString());
        Console.WriteLine("高亮文本已成功提取并保存到 ExtractedHighlightedText.txt");

        doc.Close();
    }
}

代码解析:

  • page.Annotations 属性用于访问页面上的所有批注。
  • 通过 is PdfTextMarkupAnnotationWidget 判断批注类型是否为文本标记批注。
  • textMarkupAnnotation.Bounds 获取高亮批注的矩形区域,然后利用 PdfTextExtractOptions.ExtractArea 来提取该区域的文本。
  • textMarkupAnnotation.TextMarkupColor 可以获取高亮批颜色,方便进行进一步处理或分析。

进阶技巧与常见问题解决

在实际应用中,我们可能会遇到一些更复杂的情况,以下是一些进阶技巧和常见问题解决方案。

3.1 处理乱码与编码问题

文本提取后出现乱码通常是由于编码不匹配造成的。Spire.PDF 在内部对多种编码有良好支持,但如果遇到特殊情况,可以尝试以下方法:

  • 确保字体嵌入: 如果 PDF 中的字体没有嵌入,或者使用了非常规字体,提取时可能会丢失信息或出现乱码。Spire.PDF 会尽力处理,但最佳实践是确保 PDF 生成时嵌入了所有字体。
  • 指定编码(如果 API 支持): 某些 PDF 库允许在提取时指定文本编码,但 Spire.PDF 通常会自动处理。如果仍有问题,可以检查 PDF 本身的编码信息。
  • 后处理: 对于少量难以解决的乱码,可能需要进行后处理,例如使用字符映射或替换算法。

提示: Spire.PDF 在处理多语言和复杂编码方面表现优秀,通常无需手动干预。如果出现乱码,首先确认 PDF 文件本身是否正常,或尝试更新 Spire.PDF 到最新版本。

3.2 保持文本布局与结构

仅仅提取文本有时是不够的,我们还需要了解文本在页面上的位置、大小、字体等布局信息,以便更好地还原原始文档结构。

Spire.PDF 提供了 ExtractText(bool) 重载方法或 PdfTextExtractor 类,可以获取更详细的文本元素信息,而不仅仅是纯文本字符串。例如,通过 PdfTextExtractor 我们可以获取 TextLineTextWord 对象,它们包含了文本的坐标、字体、大小等属性。

csharp 复制代码
using Spire.Pdf;
using Spire.Pdf.Texts;
using System.Drawing; // 用于 RectangleF

class Program
{
    static void Main(string[] args)
    {
        PdfDocument doc = new PdfDocument();
        doc.Load("Sample.pdf");

        PdfPageBase page = doc.Pages[0];
        PdfTextExtractor extractor = new PdfTextExtractor(page);

        // 获取页面中的所有文本行
        TextLine[] textLines = extractor.ExtractTextLines();

        foreach (TextLine line in textLines)
        {
            Console.WriteLine($"行文本: {line.Text} (位置: {line.Bounds})");
            foreach (TextWord word in line.Words)
            {
                Console.WriteLine($"  单词: {word.Text} (位置: {word.Bounds}, 字体: {word.FontName}, 大小: {word.FontSize})");
            }
        }

        doc.Close();
    }
}

代码解析:

  • extractor.ExtractTextLines() 返回一个 TextLine 数组,每个 TextLine 代表页面上的一行文本。
  • TextLine 包含 Text 属性(行文本内容)和 Bounds 属性(行在页面上的矩形区域)。
  • line.Words 进一步提供了 TextWord 数组,每个 TextWord 包含单词文本、位置、字体名称和大小等详细信息。

利用这些信息,你可以根据需求重新构建文本的布局,例如生成 HTML、XML 或其他结构化数据。

3.3 性能优化建议

对于处理大量或大型 PDF 文件,性能是一个关键考量。

  • 分批处理: 如果 PDF 文件非常大,可以考虑将其分割成小块或按页分批处理,避免一次性加载过多内容导致内存溢出。
  • 及时释放资源: 每次处理完一个 PdfDocument 实例后,务必调用 doc.Close() 方法释放其占用的内存和文件句柄。
  • 避免不必要的重复操作: 如果某个页面需要多次提取不同区域的文本,可以先创建一次 PdfTextExtractor 实例,然后多次调用其 ExtractText 方法。
  • 硬件优化: 在高性能服务器上运行,利用多核 CPU 和充足的内存,也能显著提升处理速度。
相关推荐
用户29869853014几秒前
.NET 文档自动化:Spire.Doc 设置奇偶页页眉/页脚的最佳实践
后端·c#·.net
序安InToo32 分钟前
第6课|注释与代码风格
后端·操作系统·嵌入式
xyy12332 分钟前
C#: Newtonsoft.Json 到 System.Text.Json 迁移避坑指南
后端
洋洋技术笔记34 分钟前
Spring Boot Web MVC配置详解
spring boot·后端
JxWang0535 分钟前
VS Code 配置 Markdown 环境
后端
navms38 分钟前
搞懂线程池,先把 Worker 机制啃明白
后端
JxWang0538 分钟前
离线数仓的优化及重构
后端
Nyarlathotep011339 分钟前
gin01:初探gin的启动
后端·go
JxWang0540 分钟前
安卓手机配置通用多屏协同及自动化脚本
后端
JxWang0541 分钟前
Windows Terminal 配置 oh-my-posh
后端