C# でドキュメント内の表を読み取る方法

This article was translated from English: Does it need improvement?
Translated
View the article in English

ドキュメント内の表の読み取りについて説明します。 テキストがセル内に存在し、ドキュメント全体に散在していることが多いため、プレーンな Tesseract を使用してテーブルからデータを抽出するのは難しい場合があります。 ただし、当社のライブラリには、テーブルデータを正確に検出して抽出するためにトレーニングされ、微調整された機械学習モデルが搭載されています。

単純なテーブルの場合は、簡単なテーブル検出に頼ることができますが、より複雑な構造の場合は、独自のReadDocumentAdvancedメソッドが堅牢な結果を提供し、テーブルを効果的に解析してデータを配信します。

クイックスタート: 1 回の呼び出しで複雑な表のセルを抽出する

数分で起動して実行できます。この例では、ReadDocumentAdvanced を使用した 1 回の IronOCR 呼び出しで、複雑なドキュメントから詳細なテーブル セル データを取得する方法を示します。 PDF を読み込み、高度なテーブル検出を適用し、セル情報のリストを直接返すことで、使いやすさを実証します。

Nuget Icon今すぐ NuGet で PDF を作成してみましょう:

  1. NuGet パッケージ マネージャーを使用して IronOCR をインストールします

    PM > Install-Package IronOcr

  2. このコード スニペットをコピーして実行します。

    var cells = new IronTesseract().ReadDocumentAdvanced(new OcrInput().LoadPdf("invoiceTable.pdf")).Tables.First().CellInfos;
  3. 実際の環境でテストするためにデプロイする

    今すぐ無料トライアルでプロジェクトに IronOCR を使い始めましょう
    arrow pointer

次の手順は、IronOCR を使用して表の読み取りを開始するためのガイドです。


シンプルなテーブルの例

ReadDataTablesプロパティを true に設定すると、Tesseract を使用したテーブル検出が有効になります。 この機能をテストするために、簡単な表の PDF を作成しました。ここからダウンロードできます: ' simple-table.pdf '。 この方法を使用すると、結合されたセルのない単純な表を検出できます。 より複雑なテーブルの場合は、以下に説明する方法を参照してください。

:path=/static-assets/ocr/content-code-examples/how-to/read-table-in-document-with-tesseract.cs
using IronOcr;
using System;
using System.Data;

// Instantiate OCR engine
var ocr = new IronTesseract();

// Enable table detection
ocr.Configuration.ReadDataTables = true;

using var input = new OcrPdfInput("simple-table.pdf");
var result = ocr.Read(input);

// Retrieve the data
var table = result.Tables[0].DataTable;

// Print out the table data
foreach (DataRow row in table.Rows)
{
    foreach (var item in row.ItemArray)
    {
        Console.Write(item + "\t");
    }
    Console.WriteLine();
}
Imports Microsoft.VisualBasic
Imports IronOcr
Imports System
Imports System.Data

' Instantiate OCR engine
Private ocr = New IronTesseract()

' Enable table detection
ocr.Configuration.ReadDataTables = True

Dim input = New OcrPdfInput("simple-table.pdf")
Dim result = ocr.Read(input)

' Retrieve the data
Dim table = result.Tables(0).DataTable

' Print out the table data
For Each row As DataRow In table.Rows
	For Each item In row.ItemArray
		Console.Write(item & vbTab)
	Next item
	Console.WriteLine()
Next row
$vbLabelText   $csharpLabel

請求書の読み方の例

ビジネス環境でよく見られる複雑な表の 1 つが請求書です。 請求書自体は、データの行と列を持つ複雑な表です。 IronOCR では、 ReadDocumentAdvancedメソッドを利用してこれらを美しく処理します。 このプロセスには、ドキュメントのスキャン、テーブル構造の識別、およびデータの抽出が含まれます。 この例では、" invoiceTable.pdf "ファイルを使用して、IronOCR が請求書からすべての情報を取得する方法を紹介します。

ReadDocumentAdvancedメソッドでは、基本 IronOCR パッケージと一緒にIronOcr.Extensions.AdvancedScanパッケージがインストールされている必要があります。

ブラケットオープン .NET Framework で詳細スキャンを使用するには、プロジェクトを x64 アーキテクチャで実行する必要があります。 これを実現するには、プロジェクト構成に移動し、"32 ビットを優先"オプションのチェックを外します。 詳細については、次のトラブルシューティング ガイドを参照してください:". NET Framework の高度なスキャン"。 ブラケットを閉じる

:path=/static-assets/ocr/content-code-examples/how-to/read-table-in-document-with-ml.cs
using IronOcr;
using System.Linq;

// Instantiate OCR engine
var ocr = new IronTesseract();

using var input = new OcrInput();
input.LoadPdf("invoiceTable.pdf");

// Perform OCR
var result = ocr.ReadDocumentAdvanced(input);

var cellList = result.Tables.First().CellInfos;
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

この方法は、ドキュメントのテキスト データを、境界線で囲まれたカテゴリと境界線のないカテゴリの 2 つのカテゴリに分割します。 境界線で囲まれたコンテンツの場合、ライブラリはテーブルの構造に基づいてさらにサブセクションに分割します。 結果は以下の通りです。 この方法は境界線で囲まれた情報に焦点を当てているため、複数の行にまたがる結合されたセルは 1 つのセルとして扱われることに注意することが重要です。

結果

ドキュメント内のテーブルを読む

ヘルパークラス

現在の実装では、抽出されたセルはまだ適切に整理されていません。 ただし、各セルには、X 座標、Y 座標、寸法などの貴重な情報が含まれています。 このデータを使用して、さまざまな目的のヘルパー クラスを作成できます。 以下にいくつかの基本的なヘルパー メソッドを示します。

using System;
using System.Collections.Generic;
using System.Linq;

// A helper class to process table data by sorting cells based on coordinates
public static class TableProcessor
{
    // Method to organize cells by their coordinates (Y top to bottom, X left to right)
    public static List<CellInfo> OrganizeCellsByCoordinates(List<CellInfo> cells)
    {
        // Sort cells by Y (top to bottom), then by X (left to right)
        var sortedCells = cells
            .OrderBy(cell => cell.CellRect.Y)
            .ThenBy(cell => cell.CellRect.X)
            .ToList();

        return sortedCells;
    }

    // Example method demonstrating how to process multiple tables
    public static void ProcessTables(Tables tables)
    {
        foreach (var table in tables)
        {
            var sortedCells = OrganizeCellsByCoordinates(table.CellInfos);

            Console.WriteLine("Organized Table Cells:");

            // Initialize previous Y coordinate
            int previousY = sortedCells.Any() ? sortedCells.First().CellRect.Y : 0;

            foreach (var cell in sortedCells)
            {
                // Print a new line if the Y-coordinate changes, indicating a new row
                if (Math.Abs(cell.CellRect.Y - previousY) > cell.CellRect.Height * 0.8)
                {
                    Console.WriteLine();  // Start a new row
                    previousY = cell.CellRect.Y;
                }

                // Print the cell text followed by a tab
                Console.Write($"{cell.CellText}\t");
            }

            Console.WriteLine("\n--- End of Table ---");  // End of a table
        }
    }

    // Method to extract a specific row by the given index
    public static List<CellInfo> ExtractRowByIndex(TableInfo table, int rowIndex)
    {
        if (table == null || table.CellInfos == null || !table.CellInfos.Any())
        {
            throw new ArgumentException("Table is empty or invalid.");
        }

        var sortedCells = OrganizeCellsByCoordinates(table.CellInfos);
        List<List<CellInfo>> rows = new List<List<CellInfo>>();

        // Group cells into rows based on Y coordinates
        int previousY = sortedCells.First().CellRect.Y;
        List<CellInfo> currentRow = new List<CellInfo>();

        foreach (var cell in sortedCells)
        {
            if (Math.Abs(cell.CellRect.Y - previousY) > cell.CellRect.Height * 0.8)
            {
                // Store the completed row and start a new one
                rows.Add(new List<CellInfo>(currentRow));
                currentRow.Clear();

                previousY = cell.CellRect.Y;
            }

            currentRow.Add(cell);
        }

        // Add the last row if it wasn't added yet
        if (currentRow.Any())
        {
            rows.Add(currentRow);
        }

        // Retrieve the specified row
        if (rowIndex < 0 || rowIndex >= rows.Count)
        {
            throw new IndexOutOfRangeException($"Row index {rowIndex} is out of range.");
        }

        return rows[rowIndex];
    }
}
using System;
using System.Collections.Generic;
using System.Linq;

// A helper class to process table data by sorting cells based on coordinates
public static class TableProcessor
{
    // Method to organize cells by their coordinates (Y top to bottom, X left to right)
    public static List<CellInfo> OrganizeCellsByCoordinates(List<CellInfo> cells)
    {
        // Sort cells by Y (top to bottom), then by X (left to right)
        var sortedCells = cells
            .OrderBy(cell => cell.CellRect.Y)
            .ThenBy(cell => cell.CellRect.X)
            .ToList();

        return sortedCells;
    }

    // Example method demonstrating how to process multiple tables
    public static void ProcessTables(Tables tables)
    {
        foreach (var table in tables)
        {
            var sortedCells = OrganizeCellsByCoordinates(table.CellInfos);

            Console.WriteLine("Organized Table Cells:");

            // Initialize previous Y coordinate
            int previousY = sortedCells.Any() ? sortedCells.First().CellRect.Y : 0;

            foreach (var cell in sortedCells)
            {
                // Print a new line if the Y-coordinate changes, indicating a new row
                if (Math.Abs(cell.CellRect.Y - previousY) > cell.CellRect.Height * 0.8)
                {
                    Console.WriteLine();  // Start a new row
                    previousY = cell.CellRect.Y;
                }

                // Print the cell text followed by a tab
                Console.Write($"{cell.CellText}\t");
            }

            Console.WriteLine("\n--- End of Table ---");  // End of a table
        }
    }

    // Method to extract a specific row by the given index
    public static List<CellInfo> ExtractRowByIndex(TableInfo table, int rowIndex)
    {
        if (table == null || table.CellInfos == null || !table.CellInfos.Any())
        {
            throw new ArgumentException("Table is empty or invalid.");
        }

        var sortedCells = OrganizeCellsByCoordinates(table.CellInfos);
        List<List<CellInfo>> rows = new List<List<CellInfo>>();

        // Group cells into rows based on Y coordinates
        int previousY = sortedCells.First().CellRect.Y;
        List<CellInfo> currentRow = new List<CellInfo>();

        foreach (var cell in sortedCells)
        {
            if (Math.Abs(cell.CellRect.Y - previousY) > cell.CellRect.Height * 0.8)
            {
                // Store the completed row and start a new one
                rows.Add(new List<CellInfo>(currentRow));
                currentRow.Clear();

                previousY = cell.CellRect.Y;
            }

            currentRow.Add(cell);
        }

        // Add the last row if it wasn't added yet
        if (currentRow.Any())
        {
            rows.Add(currentRow);
        }

        // Retrieve the specified row
        if (rowIndex < 0 || rowIndex >= rows.Count)
        {
            throw new IndexOutOfRangeException($"Row index {rowIndex} is out of range.");
        }

        return rows[rowIndex];
    }
}
Imports Microsoft.VisualBasic
Imports System
Imports System.Collections.Generic
Imports System.Linq

' A helper class to process table data by sorting cells based on coordinates
Public Module TableProcessor
	' Method to organize cells by their coordinates (Y top to bottom, X left to right)
	Public Function OrganizeCellsByCoordinates(ByVal cells As List(Of CellInfo)) As List(Of CellInfo)
		' Sort cells by Y (top to bottom), then by X (left to right)
		Dim sortedCells = cells.OrderBy(Function(cell) cell.CellRect.Y).ThenBy(Function(cell) cell.CellRect.X).ToList()

		Return sortedCells
	End Function

	' Example method demonstrating how to process multiple tables
	Public Sub ProcessTables(ByVal tables As Tables)
		For Each table In tables
			Dim sortedCells = OrganizeCellsByCoordinates(table.CellInfos)

			Console.WriteLine("Organized Table Cells:")

			' Initialize previous Y coordinate
			Dim previousY As Integer = If(sortedCells.Any(), sortedCells.First().CellRect.Y, 0)

			For Each cell In sortedCells
				' Print a new line if the Y-coordinate changes, indicating a new row
				If Math.Abs(cell.CellRect.Y - previousY) > cell.CellRect.Height * 0.8 Then
					Console.WriteLine() ' Start a new row
					previousY = cell.CellRect.Y
				End If

				' Print the cell text followed by a tab
				Console.Write($"{cell.CellText}" & vbTab)
			Next cell

			Console.WriteLine(vbLf & "--- End of Table ---") ' End of a table
		Next table
	End Sub

	' Method to extract a specific row by the given index
	Public Function ExtractRowByIndex(ByVal table As TableInfo, ByVal rowIndex As Integer) As List(Of CellInfo)
		If table Is Nothing OrElse table.CellInfos Is Nothing OrElse Not table.CellInfos.Any() Then
			Throw New ArgumentException("Table is empty or invalid.")
		End If

		Dim sortedCells = OrganizeCellsByCoordinates(table.CellInfos)
		Dim rows As New List(Of List(Of CellInfo))()

		' Group cells into rows based on Y coordinates
		Dim previousY As Integer = sortedCells.First().CellRect.Y
		Dim currentRow As New List(Of CellInfo)()

		For Each cell In sortedCells
			If Math.Abs(cell.CellRect.Y - previousY) > cell.CellRect.Height * 0.8 Then
				' Store the completed row and start a new one
				rows.Add(New List(Of CellInfo)(currentRow))
				currentRow.Clear()

				previousY = cell.CellRect.Y
			End If

			currentRow.Add(cell)
		Next cell

		' Add the last row if it wasn't added yet
		If currentRow.Any() Then
			rows.Add(currentRow)
		End If

		' Retrieve the specified row
		If rowIndex < 0 OrElse rowIndex >= rows.Count Then
			Throw New IndexOutOfRangeException($"Row index {rowIndex} is out of range.")
		End If

		Return rows(rowIndex)
	End Function
End Module
$vbLabelText   $csharpLabel

よくある質問

C# を使用してドキュメントのテーブルデータ抽出を改善するにはどうすればよいですか?

C#を使用して文書内のテーブルデータ抽出を強化できます。IronOCRの機械学習モデルを利用することで、複雑なテーブルデータを正確に検出および抽出できます。このアプローチは、Tesseractのような標準的なOCRツールを使用するよりも効果的です。

IronOCR の ReadDocumentAdvanced メソッドの目的は何ですか?

IronOCR の ReadDocumentAdvanced メソッドは、効果的な解析とデータ抽出を通じて堅牢な結果を提供することで複雑なテーブルを処理するように設計されています。それは、複雑な構造を持つテーブルを扱うのに特に有用です。

IronOCR を使用したテーブル抽出の開始方法は?

IronOCRを使用してテーブルを抽出するには、C#ライブラリをダウンロードし、ドキュメントを準備し、ReadDataTablesプロパティを設定してテーブル検出を有効にし、複雑なテーブルにはReadDocumentAdvancedメソッドを使用します。

IronOCRで高度なテーブル抽出に必要な追加パッケージは何ですか?

IronOCR での高度なテーブル抽出には、Windows 固有の複雑なテーブル構造を効果的に管理するための IronOcr.Extensions.AdvancedScan パッケージが必要です。

IronOCR を使用して抽出されたテーブルデータをどのように整理できますか?

IronOCR は、座標ごとに抽出されたテーブルデータを整理するためのヘルパーメソッドを提供し、複数のテーブルを処理し、特定の行をインデックス別に抽出してデータ管理を改善できます。

IronOCR で抽出されたテーブルセルに含まれるメタデータは何ですか?

IronOCR で抽出されたテーブルセルには、各セル内の X および Y 座標、セルの寸法、テキスト内容などのメタデータが含まれており、詳細なデータ分析と整理が可能です。

.NET Framework との互換性をどのように確保しますか?

IronOCR を使用してテーブル抽出をする際、.NET Frameworkとの互換性を確保するには、プロジェクトをx64アーキテクチャで実行し、プロジェクト設定で「32ビット優先」をチェックオフしてください。

カーティス・チャウ
テクニカルライター

Curtis Chauは、カールトン大学でコンピュータサイエンスの学士号を取得し、Node.js、TypeScript、JavaScript、およびReactに精通したフロントエンド開発を専門としています。直感的で美しいユーザーインターフェースを作成することに情熱を持ち、Curtisは現代のフレームワークを用いた開発や、構造の良い視覚的に魅力的なマニュアルの作成を楽しんでいます。

開発以外にも、CurtisはIoT(Internet of Things)への強い関心を持ち、ハードウェアとソフトウェアの統合方法を模索しています。余暇には、ゲームをしたりDiscordボットを作成したりして、技術に対する愛情と創造性を組み合わせています。

レビュー済み
Jeff Fritz
Jeffrey T. Fritz
プリンシパルプログラムマネージャー - .NETコミュニティチーム
Jeffはまた、.NETとVisual Studioチームのプリンシパルプログラムマネージャーです。彼は.NET Conf仮想会議シリーズのエグゼクティブプロデューサーであり、週に二回放送される開発者向けライブストリーム『Fritz and Friends』のホストを務め、テクノロジーについて話すことや視聴者と一緒にコードを書くことをしています。Jeffはワークショップ、プレゼンテーション、およびMicrosoft Build、Microsoft Ignite、.NET Conf、Microsoft MVPサミットを含む最大のMicrosoft開発者イベントのコンテンツを企画しています。
準備はできましたか?
Nuget ダウンロード 5,167,857 | Version: 2025.11 リリース