在生產環境中測試,無水印。
在任何需要的地方都能運行。
獲得 30 天的全功能產品。
在幾分鐘內上手運行。
試用產品期間完全訪問我們的支援工程團隊
從 PDF 文檔中提取結構化表格數據是 C# 開發人員的一項常見需求,這對於數據分析、報告或將信息整合到其他系統中至關重要。 然而,PDF 主要設計用於一致的視覺呈現,而非簡單的數據提取。 這會使以 C# 編程方式從 PDF 文件中讀取表格成為一項具有挑戰性的任務,特別是因為表格的形式多樣——從簡單的基於文本的網格到帶有合併單元格的複雜佈局,甚至是以圖像形式嵌入在掃描文件中的表格。
本指南提供了關於如何使用 IronPDF 進行PDF 表格提取的全面 C# 教程。 我們將主要探索利用IronPDF強大的文本提取功能來訪問並解析基於文本的PDF中的表格數據。 我們將討論此方法的有效性,提供解析策略,並提供處理提取信息的見解。 此外,我們還將討論應對更複雜情況的策略,包括掃描的 PDF。
從PDF中提取表格數據到C#的關鍵步驟
安裝IronPDF C# 函式庫(https://nuget.org/packages/IronPdf/)以進行PDF處理。
(可選示範步驟)使用 IronPDF 的 RenderHtmlAsPdf
從 HTML 字串創建一個包含表格的 PDF 範例。 (參見章節:(示範步驟)使用表格數據創建 PDF 文檔)
載入任何 PDF 文件並使用 ExtractAllText
方法提取其原始文本內容。 (參見章節:從 PDF 提取包含表格數據的所有文本)
實現 C# 邏輯以解析提取的文本並識別表格的行和單元格。 (請參閱章節:解析提取的文本以在 C# 中重建表數據)
輸出結構化的表格數據或將其保存為 CSV 文件以供進一步使用。 (請參閱章節:解析提取的文本以在 C# 中重建表數據)
考慮使用如 OCR 這樣的高級技術來處理掃描的 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 中提取文字、圖像以及(正如我們將看到的)表格數據。
要從 PDF 文件中提取表格數據,我們將設置一個 C# 專案:
Visual Studio:請確保您已安裝 Visual Studio(例如 2022)。 如果沒有,請從 Visual Studio 網站下載它(https://visualstudio.microsoft.com/downloads/)。
建立專案:
Visual Studio 的開始畫面
在 Visual Studio 中建立新的主控台應用程式
!如何在 C# 中讀取 PDF 表格,圖 3:配置新創建的應用程序
配置新創建的應用程式
選擇 .NET Framework
安裝 IronPDF:
使用 Visual Studio NuGet 套件管理員:
工具和管理 NuGet 套件
工具和管理 NuGet 套件
直接下載 NuGet 套件:訪問 IronPDF 的 NuGet 套件頁面(https://www.nuget.org/packages/IronPdf/)。
在這個教程中,我們將首先從 HTML 字串創建一個包含簡單表格的範例 PDF。 這為我們提供了一個已知的 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";
這是我們的示例表格的 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>";
現在,使用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.")
SaveAs
方法將保存 PDF。 生成的table_example.pdf
將看起來像這樣(基於HTML的概念圖片):
在 NuGet 套件管理器 UI 中搜尋 IronPDF
要提取表格數據,我們首先載入 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()
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)
要提取文本的 PDF 檔案
提取原始文本後,下一個挑戰是解析這個字串以識別和構建表格數據。 此步驟高度依賴於您PDF中表格的一致性和格式。
一般解析策略:
識別行分隔符: 換行字符 (\n
或 \r\n
) 是常見的行分隔符。
識別列分隔符號: 一行中的單元格可能會以多個空格、標籤或特定已知字符(如 ' ' 或者 '; 有時候,如果欄位在視覺上對齊但缺乏明確的文字定界符號,您可能會根據一致的間距模式推斷其結構,儘管這較為複雜。
過濾非表格內容: 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
此程式碼將文字拆分為行。 if
條件是一個非常基本的篩選器,適用於此具體示例的非表格文本。 在實際情境中,您需要更健全的邏輯來準確識別和解析表格行和單元格。
簡單過濾文本的輸出:
控制台顯示提取的文本
文字剖析方法的重要考量:
限制:此方法可能會遇到以下困難:
具有合併單元格或複雜的嵌套結構的表格。
透過視覺間距而非文本分隔符定義欄位的表格。
嵌入為圖像的表格(需要 OCR)。
您可以將篩選後的行(理想情況下表示表格行)保存到 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")
從複雜或基於圖像的 PDF 表格中提取數據通常需要比簡單文本解析更高級的技術。 IronPDF 提供的功能可以協助:
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
欲獲取詳細指導,請造訪 IronOCR 文件 (https://ironsoftware.com/csharp/ocr/)。 在光學字符識別 (OCR) 後,您需要解析得到的文本字串。
ExtractAllText()
提供了文本流,但某些情況下可能需要知道每個文本片段的 x,y 座標。 如果 IronPDF 提供獲取包含邊界框資訊的文字的 API(請檢查目前的文件),這可能會允許進行更精細的空間解析,以根據視覺對齊重新構建表格。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.
模式識別與正則表達式: 對於具有非常可預測模式但分隔符不一致的表格,有時候可以運用複雜的正則表達式來處理提取出的文本以獨立表格數據。
選擇正確的策略取決於來源PDF的複雜性和一致性。 對於許多包含文字型表格的常見商業文件,IronPDF 的ExtractAllText
結合智能 C# 解析邏輯可以非常有效。對於基於圖像的表格,其 OCR 功能是必不可少的。
本文展示了如何使用 IronPDF 在 C# 中從 PDF 文件中提取表數據,主要集中在利用 ExtractAllText()
方法並進行後續的字串解析。 我們已經看到,雖然這種方法對基於文本的表格來說非常強大,但更複雜的場景(如基於圖像的表格)可以通過使用IronPDF的OCR功能或首先將PDF轉換為其他格式來解決。
IronPDF 為 .NET 開發者提供了一個多功能的工具包,簡化了許多與 PDF 相關的任務,從創建和編輯到全面的數據提取。 它提供了像DOCX等格式轉換為PDF。
IronPDF 可免費用於開發,並提供免費試用許可證以測試其完整商業功能。 針對生產部署,提供各種授權選項。
如需更多詳細資訊和進階使用案例,請瀏覽官方 IronPDF 文件和範例(https://ironpdf.com/)