位置: 文档库 > C#(.NET) > C# 实现将 PDF 转文本的功能

C# 实现将 PDF 转文本的功能

长跪读素书 上传于 2022-10-09 10:22

《C# 实现将 PDF 转文本的功能》

在现代办公和数据处理场景中,PDF 作为跨平台、格式稳定的文档格式被广泛使用。但当我们需要提取其中的文本内容进行编辑、分析或索引时,直接操作 PDF 文件往往不够便捷。通过 C# 实现 PDF 转文本的功能,可以高效地将文档内容转化为可编辑的纯文本格式,为后续处理提供基础。本文将详细介绍如何使用 C# 结合开源库 iTextSharp(或 iText7)和 PDFBox 的 .NET 封装版(如 PDFBox.NET)实现这一功能,涵盖基础实现、异常处理、性能优化及多线程处理等核心内容。

一、技术选型与库介绍

实现 PDF 转文本的核心在于解析 PDF 的页面内容并提取文本流。以下是常用的 .NET 库:

  • iTextSharp(iText7 的 .NET 版本):功能强大,支持 PDF 创建、修改和文本提取,但商业使用需购买许可证(AGPL 协议下开源版本需遵守条款)。
  • PDFBox.NET:Apache PDFBox 的 .NET 封装,完全开源(Apache 2.0 协议),适合商业项目。
  • PdfPig:轻量级开源库,专注于文本提取,性能较好。

本文以 iTextSharpPDFBox.NET 为例,展示两种实现方式。

二、使用 iTextSharp 实现 PDF 转文本

1. 安装 NuGet 包

通过 Visual Studio 的 NuGet 包管理器安装 itext7(或旧版 itextsharp):

Install-Package itext7

2. 基础实现代码

以下代码演示如何从 PDF 文件中提取文本:

using iText.Kernel.Pdf;
using iText.Kernel.Pdf.Canvas.Parser;
using System;
using System.IO;

public class PdfToTextConverter
{
    public static string ExtractTextFromPdf(string filePath)
    {
        if (!File.Exists(filePath))
        {
            throw new FileNotFoundException("PDF 文件未找到", filePath);
        }

        using (var reader = new PdfReader(filePath))
        using (var pdfDoc = new PdfDocument(reader))
        {
            var text = new System.Text.StringBuilder();

            for (int i = 1; i 

3. 异常处理与优化

实际项目中需处理以下异常:

  • 文件权限不足
  • PDF 加密或损坏
  • 大文件内存占用

优化后的代码:

public static string ExtractTextFromPdfSafely(string filePath)
{
    try
    {
        if (string.IsNullOrWhiteSpace(filePath))
            throw new ArgumentException("文件路径不能为空");

        using (var reader = new PdfReader(filePath))
        using (var pdfDoc = new PdfDocument(reader))
        {
            var text = new System.Text.StringBuilder();
            var pageCount = pdfDoc.GetNumberOfPages();

            for (int i = 1; i 

三、使用 PDFBox.NET 实现 PDF 转文本

1. 安装 NuGet

Install-Package PdfBox.Net

2. 基础实现代码

PDFBox.NET 的 API 更接近 Java 版本,代码如下:

using org.apache.pdfbox.pdmodel;
using org.apache.pdfbox.text;
using System;
using System.IO;

public class PdfBoxConverter
{
    public static string ExtractTextWithPdfBox(string filePath)
    {
        if (!File.Exists(filePath))
            throw new FileNotFoundException("PDF 文件未找到", filePath);

        using (var document = PDDocument.Load(new FileStream(filePath, FileMode.Open)))
        {
            var textStripper = new PDFTextStripper();
            return textStripper.GetText(document);
        }
    }
}

// 调用示例
var text = PdfBoxConverter.ExtractTextWithPdfBox(@"C:\test.pdf");
Console.WriteLine(text);

3. 处理加密 PDF

若 PDF 受密码保护,需提供密码:

public static string ExtractTextFromEncryptedPdf(string filePath, string password)
{
    try
    {
        var loadParams = new LoadParams(filePath)
        {
            Password = password
        };

        using (var document = PDDocument.Load(loadParams))
        {
            var stripper = new PDFTextStripper();
            return stripper.GetText(document);
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine($"解密失败: {ex.Message}");
        return string.Empty;
    }
}

四、性能优化与多线程处理

对于大文件或多文件批量处理,单线程可能效率低下。以下是一个多线程实现的示例:

using System.Collections.Concurrent;
using System.Threading.Tasks;

public class ParallelPdfProcessor
{
    public static ConcurrentBag ProcessMultipleFiles(string[] filePaths)
    {
        var results = new ConcurrentBag();

        Parallel.ForEach(filePaths, filePath =>
        {
            try
            {
                var text = PdfToTextConverter.ExtractTextFromPdfSafely(filePath);
                results.Add($"文件: {filePath}\n内容长度: {text.Length}\n");
            }
            catch (Exception ex)
            {
                results.Add($"处理 {filePath} 失败: {ex.Message}");
            }
        });

        return results;
    }
}

// 调用示例
var files = new[] { @"C:\1.pdf", @"C:\2.pdf" };
var results = ParallelPdfProcessor.ProcessMultipleFiles(files);
foreach (var result in results)
{
    Console.WriteLine(result);
}

五、高级功能扩展

1. 保留格式信息

若需保留换行符、缩进等格式,可在提取时记录位置信息(需深入解析 PDF 的布局对象)。

2. 筛选特定内容

通过正则表达式筛选关键信息(如日期、电话号码):

var pattern = @"\d{3}-\d{4}-\d{4}"; // 示例:匹配电话号码
var matches = Regex.Matches(text, pattern);
foreach (Match match in matches)
{
    Console.WriteLine(match.Value);
}

3. 输出为结构化数据

将文本按章节或段落分割,存储为 JSON:

using System.Text.Json;

public class PdfSection
{
    public int PageNumber { get; set; }
    public string Content { get; set; }
}

public static string ConvertToJson(string text)
{
    var sections = new List();
    // 假设按 "第X章" 分割(实际需更复杂的解析)
    var chapters = text.Split(new[] { "第" }, StringSplitOptions.RemoveEmptyEntries);
    foreach (var chapter in chapters)
    {
        sections.Add(new PdfSection { Content = chapter });
    }
    return JsonSerializer.Serialize(sections);
}

六、常见问题与解决方案

1. 提取的文本乱码

原因:PDF 使用非标准字体编码。解决方案:

  • 尝试更新库版本
  • 使用 OCR 工具(如 Tesseract)处理扫描件 PDF

2. 内存不足

对于超大文件,分页读取或使用流式处理:

// iText7 分页处理示例
public static void ProcessLargePdf(string filePath)
{
    using (var reader = new PdfReader(filePath))
    using (var pdfDoc = new PdfDocument(reader))
    {
        for (int i = 1; i 

3. 商业使用许可

iTextSharp 的 AGPL 协议要求开源修改后的代码。若需闭源商业使用,建议:

  • 购买 iText 商业许可证
  • 选择 PDFBox.NET 或 PdfPig 等 Apache 2.0 协议库

七、完整示例项目结构

一个完整的控制台应用示例:

// Program.cs
using System;

class Program
{
    static void Main(string[] args)
    {
        if (args.Length == 0)
        {
            Console.WriteLine("请指定 PDF 文件路径");
            return;
        }

        var filePath = args[0];
        var text = PdfToTextConverter.ExtractTextFromPdfSafely(filePath);

        if (!string.IsNullOrEmpty(text))
        {
            Console.WriteLine("提取成功,保存到文件?(Y/N)");
            var save = Console.ReadLine()?.ToUpper() == "Y";
            if (save)
            {
                var outputPath = Path.Combine(
                    Path.GetDirectoryName(filePath),
                    Path.GetFileNameWithoutExtension(filePath) + ".txt");
                File.WriteAllText(outputPath, text);
                Console.WriteLine($"已保存至 {outputPath}");
            }
        }
    }
}

八、总结与展望

通过 C# 实现 PDF 转文本功能,可以灵活应对文档处理需求。iTextSharp 适合需要精细控制的高级场景,而 PDFBox.NET 则提供了更宽松的开源许可。未来,随着 AI 技术的发展,结合 OCR 和自然语言处理(NLP)可以进一步提升文本提取的准确性和实用性。

关键词:C#、PDF转文本、iTextSharp、PDFBox.NET、多线程处理、异常处理、文本提取、NuGet、开源库、性能优化

简介:本文详细介绍了使用 C# 通过 iTextSharp 和 PDFBox.NET 库实现 PDF 转文本的功能,涵盖基础实现、异常处理、性能优化及多线程处理,适用于需要提取 PDF 文本内容的开发场景。