使用IRONPDF

如何在C#中读取PDF表格

从 PDF 文档中提取结构化表格数据是 C# 开发人员的常见需求,这对于数据分析、报告或将信息集成到其他系统中至关重要。 然而,PDF 主要设计用于一致的视觉呈现,而不是直接的数据提取。 这使得以编程方式从PDF文件中读取表格在C#中成为一项具有挑战性的任务,特别是因为表格可能有很大不同——从简单的基于文本的网格到具有合并单元格的复杂布局,甚至是嵌入在扫描文档中的图像形式的表格。

本指南提供了关于如何使用IronPDF进行PDF表格提取的全面C#教程。 我们将主要探索利用IronPDF强大的文本提取功能,从基于文本的PDF中访问并解析表格数据。 我们将讨论这种方法的有效性,提供解析策略,并提供处理提取信息的见解。 此外,我们还将讨论应对更复杂情况的策略,包括扫描的PDF。


在C#中从PDF提取表格数据的关键步骤

  1. 安装用于PDF处理的IronPDF C#库(https://nuget.org/packages/IronPdf/)。

  2. (可选演示步骤)使用 IronPDF 的 RenderHtmlAsPdf 从 HTML 字符串创建包含表格的示例 PDF。 (请参见章节:(演示步骤)使用表格数据创建 PDF 文档)

  3. 加载任何PDF文档,并使用ExtractAllText方法检索其原始文本内容。 (请参见章节:从PDF中提取包含表格数据的所有文本)

  4. 实现 C# 逻辑以解析提取的文本并识别表格行和单元格。 (请参见章节:在C#中解析提取的文本以重建表格数据)

  5. 输出结构化的表格数据或将其保存到CSV文件中以供进一步使用。 (请参见章节:在C#中解析提取的文本以重建表格数据)

  6. 考虑使用高级技术,例如用于扫描PDF的OCR(稍后讨论)。


IronPDF - C# PDF库

IronPDF 是一个C# .NET 库解决方案,用于在 .NET 中操作 PDF (https://ironpdf.com/),帮助开发人员在他们的软件应用程序中轻松读取、创建和编辑 PDF 文档。 其强大的Chromium引擎能够以高精度和速度从HTML渲染PDF文档。 它允许开发人员从不同格式无缝转换为 PDF,反之亦然。 它支持最新的 .NET 框架,包括 .NET 7、.NET 6、5、4、.NET Core 和 Standard。

此外,IronPDF .NET API 还使开发人员能够操作和编辑 PDF,添加页眉和页脚,并且更重要的是,可以轻松地从 PDF 中提取文本、图像和(正如我们将看到的)表格数据。

一些重要功能包括:

使用IronPDF库在C#中提取表格数据的步骤

要从PDF文档中提取表格数据,我们将设置一个C#项目:

  1. Visual Studio:确保您已安装 Visual Studio(例如,2022)。 如果没有,请从 Visual Studio 网站下载 (https://visualstudio.microsoft.com/downloads/)。

  2. 创建项目

    • 打开 Visual Studio 2022,点击创建新项目

    如何在C#中读取PDF表格,图1:Visual Studio的启动界面

    Visual Studio 的开始屏幕

    • 选择“控制台应用”(或您喜欢的C#项目类型),然后点击下一步

    如何在C#中读取PDF表格,图2:在Visual Studio中创建一个新的控制台应用程序

    在 Visual Studio 中创建一个新的控制台应用程序

    • 为您的项目命名(例如,“ReadPDFTableDemo”),然后点击下一步

    如何用C#读取PDF表格,图3:配置新创建的应用程序

    配置新创建的应用程序

    • 选择您所需的.NET框架(例如.NET 6或更高版本)。

    如何在C#中读取PDF表格,第4步:选择.NET Framework

    选择一个 .NET Framework

    • 点击创建。 控制台项目将被创建。
  3. 安装 IronPDF

    • 使用 Visual Studio NuGet 包管理器

      • 在解决方案资源管理器中右键单击您的项目,选择“管理 NuGet 包...”

    如何在C#中读取PDF表格,图5:工具和管理NuGet包

    工具和管理NuGet软件包

    • 在 NuGet 包管理器中,浏览 "IronPdf" 并点击 "Install"。

    如何在C#中读取PDF表格,图6:工具与管理NuGet包

    工具和管理NuGet软件包

(演示步骤)创建带有表格数据的PDF文档

在本教程中,我们将首先创建一个包含简单表格的样例PDF,该表格来自一个HTML字符串。 这为我们提供了一个已知的PDF结构,以展示提取过程。 在实际场景中,您将加载您已有的PDF文件。

添加IronPDF命名空间,并可选择设置您的许可证密钥(IronPDF在开发过程中免费使用,但在商业部署中不带水印需要许可证):

using IronPdf;
using System;       // For StringSplitOptions, Console
using System.IO;    // For StreamWriter

// Apply your license key if you have one. Otherwise, IronPDF runs in trial mode.
// License.LicenseKey = "YOUR-TRIAL/PURCHASED-LICENSE-KEY";
using IronPdf;
using System;       // For StringSplitOptions, Console
using System.IO;    // For StreamWriter

// Apply your license key if you have one. Otherwise, IronPDF runs in trial mode.
// License.LicenseKey = "YOUR-TRIAL/PURCHASED-LICENSE-KEY";
Imports IronPdf
Imports System ' For StringSplitOptions, Console
Imports System.IO ' For StreamWriter

' Apply your license key if you have one. Otherwise, IronPDF runs in trial mode.
' License.LicenseKey = "YOUR-TRIAL/PURCHASED-LICENSE-KEY";
$vbLabelText   $csharpLabel

这是我们示例表格的HTML字符串:

string HTML = "<html>" +
        "<style>" +
            "table, th, td {" +
                "border:1px solid black;" +
            "}" +
        "</style>" +
        "<body>" +
            "<h1>A Simple table example</h1>" + // Corrected typo: h1 not h2
            "<table>" +
                "<tr>" +
                    "<th>Company</th>" +
                    "<th>Contact</th>" +
                    "<th>Country</th>" +
               "</tr>" +
                "<tr>" +
                    "<td>Alfreds Futterkiste</td>" +
                    "<td>Maria Anders</td>" +
                    "<td>Germany</td>" +
                "</tr>" +
                "<tr>" +
                    "<td>Centro comercial Moctezuma</td>" +
                    "<td>Francisco Chang</td>" +
                    "<td>Mexico</td>" +
                "</tr>" +
            "</table>" +
            "<p>To understand the example better, we have added borders to the table.</p>" +
        "</body>" +
        "</html>";
string HTML = "<html>" +
        "<style>" +
            "table, th, td {" +
                "border:1px solid black;" +
            "}" +
        "</style>" +
        "<body>" +
            "<h1>A Simple table example</h1>" + // Corrected typo: h1 not h2
            "<table>" +
                "<tr>" +
                    "<th>Company</th>" +
                    "<th>Contact</th>" +
                    "<th>Country</th>" +
               "</tr>" +
                "<tr>" +
                    "<td>Alfreds Futterkiste</td>" +
                    "<td>Maria Anders</td>" +
                    "<td>Germany</td>" +
                "</tr>" +
                "<tr>" +
                    "<td>Centro comercial Moctezuma</td>" +
                    "<td>Francisco Chang</td>" +
                    "<td>Mexico</td>" +
                "</tr>" +
            "</table>" +
            "<p>To understand the example better, we have added borders to the table.</p>" +
        "</body>" +
        "</html>";
HTML

现在,使用ChromePdfRenderer从此 HTML 创建 PDF:

var renderer = new ChromePdfRenderer();
PdfDocument pdfDocument = renderer.RenderHtmlAsPdf(HTML);
pdfDocument.SaveAs("table_example.pdf");
Console.WriteLine("Sample PDF 'table_example.pdf' created.");
var renderer = new ChromePdfRenderer();
PdfDocument pdfDocument = renderer.RenderHtmlAsPdf(HTML);
pdfDocument.SaveAs("table_example.pdf");
Console.WriteLine("Sample PDF 'table_example.pdf' created.");
Dim renderer = New ChromePdfRenderer()
Dim pdfDocument As PdfDocument = renderer.RenderHtmlAsPdf(HTML)
pdfDocument.SaveAs("table_example.pdf")
Console.WriteLine("Sample PDF 'table_example.pdf' created.")
$vbLabelText   $csharpLabel

SaveAs 方法保存 PDF。 生成的table_example.pdf将如下所示(基于HTML的概念图):

如何在C#中读取PDF表,图7:在NuGet包管理器UI中搜索IronPDF

在NuGet包管理器UI中搜索IronPDF

从PDF中提取包含表格数据的所有文本

要提取表格数据,首先加载 PDF(无论是我们刚创建的 PDF 还是任何现有的 PDF),然后使用 ExtractAllText 方法。 此方法从PDF页面中检索所有文本内容。

// Load the PDF (if you just created it, it's already loaded in pdfDocument)
// If loading an existing PDF:
// PdfDocument pdfDocument = PdfDocument.FromFile("table_example.pdf"); 
// Or use the one created above:
string allText = pdfDocument.ExtractAllText();
// Load the PDF (if you just created it, it's already loaded in pdfDocument)
// If loading an existing PDF:
// PdfDocument pdfDocument = PdfDocument.FromFile("table_example.pdf"); 
// Or use the one created above:
string allText = pdfDocument.ExtractAllText();
' Load the PDF (if you just created it, it's already loaded in pdfDocument)
' If loading an existing PDF:
' PdfDocument pdfDocument = PdfDocument.FromFile("table_example.pdf"); 
' Or use the one created above:
Dim allText As String = pdfDocument.ExtractAllText()
$vbLabelText   $csharpLabel

allText变量现在包含PDF的所有文本内容。 您可以显示它以查看原始提取:

Console.WriteLine("\n--- Raw Extracted Text ---");
Console.WriteLine(allText);
Console.WriteLine("\n--- Raw Extracted Text ---");
Console.WriteLine(allText);
Imports Microsoft.VisualBasic

Console.WriteLine(vbLf & "--- Raw Extracted Text ---")
Console.WriteLine(allText)
$vbLabelText   $csharpLabel

如何在 C# 中读取 PDF 表,图 8:要提取文本的 PDF 文件

要提取文本的PDF文件

解析提取的文本以在C#中重建表格数据

在提取原始文本后,下一个挑战是解析此字符串以识别和构建表格数据。 这一步高度依赖于您PDF中表格的一致性和格式。

常规解析策略:

  1. 识别行分隔符:换行符(\n\r\n)是常见的行分隔符。

  2. 识别列分隔符: 行内的单元格可能由多个空格、制表符或特定已知字符(如“ ' 或 '; 有时候,如果列在视觉上对齐但缺乏明确的文本分隔符,您可能会基于一致的间距模式来推断结构,尽管这更为复杂。

  3. 过滤非表格内容: ExtractAllText 方法获取所有文本。 您需要通过查找标题关键词或跳过前言/后记文本的方式,使用逻辑来分离出实际构成表格的文本。

    C# String.Split 方法是实现这一点的基本工具。 以下是一个示例,尝试从我们的样本中仅提取表格行,过滤掉带有句号的行(这是针对这个特定示例的简单启发式方法):

Console.WriteLine("\n--- Parsed Table Data (Simple Heuristic) ---");
string[] textLines = allText.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
foreach (string line in textLines)
{
    // Simple filter: skip lines with a period, assuming they are not table data in this example
    // and skip lines that are too short or headers if identifiable
    if (line.Contains(".") 
 line.Contains("A Simple table example") 
 line.Length < 5) 
    {
        continue;
    }
    else
    {
        // Further split line into cells based on expected delimiters (e.g., multiple spaces)
        // This part requires careful adaptation to your PDF's table structure
        // Example: string[] cells = line.Split(new[] { "  ", "\t" }, StringSplitOptions.None);
        Console.WriteLine(line); // For now, just print the filtered line
    }
}
Console.WriteLine("\n--- Parsed Table Data (Simple Heuristic) ---");
string[] textLines = allText.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
foreach (string line in textLines)
{
    // Simple filter: skip lines with a period, assuming they are not table data in this example
    // and skip lines that are too short or headers if identifiable
    if (line.Contains(".") 
 line.Contains("A Simple table example") 
 line.Length < 5) 
    {
        continue;
    }
    else
    {
        // Further split line into cells based on expected delimiters (e.g., multiple spaces)
        // This part requires careful adaptation to your PDF's table structure
        // Example: string[] cells = line.Split(new[] { "  ", "\t" }, StringSplitOptions.None);
        Console.WriteLine(line); // For now, just print the filtered line
    }
}
Imports Microsoft.VisualBasic

Console.WriteLine(vbLf & "--- Parsed Table Data (Simple Heuristic) ---")
Dim textLines() As String = allText.Split( { ControlChars.Cr, ControlChars.Lf }, StringSplitOptions.RemoveEmptyEntries)
For Each line As String In textLines
	' Simple filter: skip lines with a period, assuming they are not table data in this example
	' and skip lines that are too short or headers if identifiable
	If line.Contains(".") line.Contains("A Simple table example") line.Length < 5 Then
		Continue For
	Else
		' Further split line into cells based on expected delimiters (e.g., multiple spaces)
		' This part requires careful adaptation to your PDF's table structure
		' Example: string[] cells = line.Split(new[] { "  ", "\t" }, StringSplitOptions.None);
		Console.WriteLine(line) ' For now, just print the filtered line
	End If
Next line
$vbLabelText   $csharpLabel

此代码将文本分成多行。 if 条件是针对这个具体示例中的非表格文本的一个非常基本的过滤器。 在实际场景中,您需要更健壮的逻辑来准确识别和解析表行和单元格。

简单过滤文本的输出:

如何在C#中读取PDF表格,图9:控制台显示提取的文本

控制台显示提取的文本

文本解析方法的重要注意事项:

  • 最适合: 具有简单、一致的表格结构和清晰文本分隔符的文本型PDF。
  • 限制:此方法可能在以下方面遇到困难:

    • 具有合并单元格或复杂嵌套结构的表格。

    • 表格中的列是通过视觉间距而不是文本分隔符来定义的。

    • 作为图像嵌入的表格(需要 OCR)。

    • PDF生成中的变化导致文本提取顺序不一致。

    您可以将过滤的行(理想情况下代表表格行)保存到CSV文件中:

using (StreamWriter file = new StreamWriter("parsed_table_data.csv", false))
{
    file.WriteLine("Company,Contact,Country"); // Write CSV Header
    foreach (string line in textLines)
    {
        if (line.Contains(".") 
 line.Contains("A Simple table example") 
 line.Length < 5)
        {
            continue;
        }
        else
        {
            // For a real CSV, you'd split 'line' into cells and join with commas
            // E.g., string[] cells = line.Split(new[] {"  "}, StringSplitOptions.RemoveEmptyEntries);
            // string csvLine = string.Join(",", cells);
            // file.WriteLine(csvLine);
            file.WriteLine(line.Replace("  ", ",").Trim()); // Basic replacement for this example
        }
    }
}
Console.WriteLine("\nFiltered table data saved to parsed_table_data.csv");
using (StreamWriter file = new StreamWriter("parsed_table_data.csv", false))
{
    file.WriteLine("Company,Contact,Country"); // Write CSV Header
    foreach (string line in textLines)
    {
        if (line.Contains(".") 
 line.Contains("A Simple table example") 
 line.Length < 5)
        {
            continue;
        }
        else
        {
            // For a real CSV, you'd split 'line' into cells and join with commas
            // E.g., string[] cells = line.Split(new[] {"  "}, StringSplitOptions.RemoveEmptyEntries);
            // string csvLine = string.Join(",", cells);
            // file.WriteLine(csvLine);
            file.WriteLine(line.Replace("  ", ",").Trim()); // Basic replacement for this example
        }
    }
}
Console.WriteLine("\nFiltered table data saved to parsed_table_data.csv");
Imports Microsoft.VisualBasic

Using file As New StreamWriter("parsed_table_data.csv", False)
	file.WriteLine("Company,Contact,Country") ' Write CSV Header
	For Each line As String In textLines
		If line.Contains(".") line.Contains("A Simple table example") line.Length < 5 Then
			Continue For
		Else
			' For a real CSV, you'd split 'line' into cells and join with commas
			' E.g., string[] cells = line.Split(new[] {"  "}, StringSplitOptions.RemoveEmptyEntries);
			' string csvLine = string.Join(",", cells);
			' file.WriteLine(csvLine);
			file.WriteLine(line.Replace("  ", ",").Trim()) ' Basic replacement for this example
		End If
	Next line
End Using
Console.WriteLine(vbLf & "Filtered table data saved to parsed_table_data.csv")
$vbLabelText   $csharpLabel

在 C# 中进行更复杂的 PDF 表格提取的策略

从复杂或基于图像的PDF表格中提取数据通常需要比简单文本解析更先进的技术。 IronPDF 提供的功能可以协助:

  • 使用IronOCR的功能处理扫描表格: 如果表格在图像中(例如,扫描的PDF),仅使用ExtractAllText() 无法将其捕获。 IronOCR 的文字检测 功能可以先将这些图像转换为文本。
// Conceptual OCR usage (refer to IronOCR's documentation for detailed implementation)
// Install Package IronOcr
using IronOcr;
using (var ocrInput = new OcrInput("scanned_pdf_with_table.pdf"))
{
     ocrInput.TargetDPI = 300; // Good DPI for OCR accuracy
     var ocrResult = new IronOcr().Read(ocrInput);
     string ocrExtractedText = ocrResult.Text;
     // Now, apply parsing logic to 'ocrExtractedText'
     Console.WriteLine("\n--- OCR Extracted Text for Table Parsing ---");
     Console.WriteLine(ocrExtractedText);
}
// Conceptual OCR usage (refer to IronOCR's documentation for detailed implementation)
// Install Package IronOcr
using IronOcr;
using (var ocrInput = new OcrInput("scanned_pdf_with_table.pdf"))
{
     ocrInput.TargetDPI = 300; // Good DPI for OCR accuracy
     var ocrResult = new IronOcr().Read(ocrInput);
     string ocrExtractedText = ocrResult.Text;
     // Now, apply parsing logic to 'ocrExtractedText'
     Console.WriteLine("\n--- OCR Extracted Text for Table Parsing ---");
     Console.WriteLine(ocrExtractedText);
}
' Conceptual OCR usage (refer to IronOCR's documentation for detailed implementation)
' Install Package IronOcr
Imports Microsoft.VisualBasic
Imports IronOcr
Using ocrInput As New OcrInput("scanned_pdf_with_table.pdf")
	 ocrInput.TargetDPI = 300 ' Good DPI for OCR accuracy
	 Dim ocrResult = (New IronOcr()).Read(ocrInput)
	 Dim ocrExtractedText As String = ocrResult.Text
	 ' Now, apply parsing logic to 'ocrExtractedText'
	 Console.WriteLine(vbLf & "--- OCR Extracted Text for Table Parsing ---")
	 Console.WriteLine(ocrExtractedText)
End Using
$vbLabelText   $csharpLabel

有关详细指南,请访问 IronOCR 文档(https://ironsoftware.com/csharp/ocr/)。 执行OCR后,您将解析生成的文本字符串。

  • 基于坐标的文本提取(高级): 虽然IronPDF的ExtractAllText()提供了文本流,但某些情况下可能会从了解每个文本片段的x,y坐标中受益。 如果IronPDF提供API来获取包含其边界框信息的文本(请检查当前文档),这可能允许进行更复杂的空间解析,以基于视觉对齐重建表格。
  • 将PDF转换为其他格式: IronPDF可以将PDF转换为像HTML这样的结构化格式。 通常,解析 HTML 表格比解析原始 PDF 文本更简单。
PdfDocument pdfToConvert = PdfDocument.FromFile("your_document.pdf");
string htmlOutput = pdfToConvert.ToHtmlString();
// Then use an HTML parsing library (e.g., HtmlAgilityPack) to extract tables from htmlOutput.
PdfDocument pdfToConvert = PdfDocument.FromFile("your_document.pdf");
string htmlOutput = pdfToConvert.ToHtmlString();
// Then use an HTML parsing library (e.g., HtmlAgilityPack) to extract tables from htmlOutput.
Dim pdfToConvert As PdfDocument = PdfDocument.FromFile("your_document.pdf")
Dim htmlOutput As String = pdfToConvert.ToHtmlString()
' Then use an HTML parsing library (e.g., HtmlAgilityPack) to extract tables from htmlOutput.
$vbLabelText   $csharpLabel
  • 模式识别和正则表达式:对于具有非常可预测模式但分隔符不一致的表,应用于提取文本的复杂正则表达式有时可以隔离表数据。

    选择正确的策略取决于源PDF的复杂性和一致性。 对于许多带有基于文本表格的常见商业文档,IronPDF的ExtractAllText结合智能C#解析逻辑可以非常有效。对于基于图像的表格,其OCR功能是必不可少的。

摘要

本文演示了如何使用IronPDF在C#中从PDF文档中提取表格数据,主要关注于利用ExtractAllText()方法以及随后的字符串解析。 我们已经看到,这种方法虽然对基于文本的表格非常有效,但更复杂的场景,例如基于图像的表格,可以通过使用IronPDF的OCR功能来处理,或者首先将PDF转换为其他格式。

IronPDF为.NET开发人员提供了一个多功能工具包,简化了从创建和编辑到全面数据提取的许多PDF相关任务。 它提供了像DOCX等格式转换为PDF。

IronPDF是免费的开发工具,并提供免费试用许可以测试其全部商业功能。 对于生产部署,有多种许可选项可供选择。

欲了解更多详细信息和高级用例,请查看官方IronPDF文档和示例(https://ironpdf.com/

Chipego
软件工程师
Chipego 拥有出色的倾听技巧,这帮助他理解客户问题并提供智能解决方案。他在 2023 年加入 Iron Software 团队,此前他获得了信息技术学士学位。IronPDF 和 IronOCR 是 Chipego 主要专注的两个产品,但他对所有产品的了解每天都在增长,因为他不断找到支持客户的新方法。他喜欢 Iron Software 的合作氛围,公司各地的团队成员贡献他们丰富的经验,以提供有效的创新解决方案。当 Chipego 离开办公桌时,你经常可以发现他在看书或踢足球。
< 前一页
如何将二维码转换为PDF
下一步 >
C# 教程:使用 IronPDF 构建 PDF 文本内容查看器(Windows 窗体)