密集した表からの無順序テキスト抽出

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

密集した表またはフォームレイアウトから抽出されたテキストは乱雑に見えます。 隣接する行からの文字が混ぜ合わされており、例として"ユニーク番号123456789"が"U123456789nique Number"として抽出されます。

これは、密集したレイアウトに対するpage.Lines抽出の既知の制限です。 page.Linesは、構成できない組み込みの垂直許容差を使用して文字をグループ化します。 表セル内の2つの可視行がわずか1ポイントまたは2つだけ離れて座っている場合、グループ化器は両方の行を1つの論理行に折りたたみ、左から右へ文字を並べ替え、それらを連続して挿入します。 ExtractTextFromPage(i)メソッドはコンテンツストリーム順にデフォルト設定されていますが、フォームPDFでは視覚的な読み順と一致しない場合があります。

解決策

推奨: 調整可能なトレランスでTextChunksを使用する

BoundingBoxを公開しており、垂直位置でグループ化し、各行内を水平位置で並べ替えることができます:

using IronPdf.Pages;
using System.Text;

static string ExtractTextUsingTextChunks(IPdfPage page, double rowTolerance = 2.0)
{
    var rows = page.TextChunks
        .Where(c => !string.IsNullOrWhiteSpace(c.Contents))
        .GroupBy(c => Math.Round(c.BoundingBox.Top / rowTolerance) * rowTolerance)
        .OrderByDescending(g => g.Key);

    var extractedText = new StringBuilder();
    foreach (var row in rows)
    {
        var line = string.Join(" ",
            row.OrderBy(c => c.BoundingBox.Left)
               .Select(c => c.Contents.Trim())
               .Where(text => !string.IsNullOrWhiteSpace(text)));
        extractedText.AppendLine(line);
    }
    return extractedText.ToString();
}
using IronPdf.Pages;
using System.Text;

static string ExtractTextUsingTextChunks(IPdfPage page, double rowTolerance = 2.0)
{
    var rows = page.TextChunks
        .Where(c => !string.IsNullOrWhiteSpace(c.Contents))
        .GroupBy(c => Math.Round(c.BoundingBox.Top / rowTolerance) * rowTolerance)
        .OrderByDescending(g => g.Key);

    var extractedText = new StringBuilder();
    foreach (var row in rows)
    {
        var line = string.Join(" ",
            row.OrderBy(c => c.BoundingBox.Left)
               .Select(c => c.Contents.Trim())
               .Where(text => !string.IsNullOrWhiteSpace(text)));
        extractedText.AppendLine(line);
    }
    return extractedText.ToString();
}
Imports IronPdf.Pages
Imports System.Text

Private Shared Function ExtractTextUsingTextChunks(page As IPdfPage, Optional rowTolerance As Double = 2.0) As String
    Dim rows = page.TextChunks _
        .Where(Function(c) Not String.IsNullOrWhiteSpace(c.Contents)) _
        .GroupBy(Function(c) Math.Round(c.BoundingBox.Top / rowTolerance) * rowTolerance) _
        .OrderByDescending(Function(g) g.Key)

    Dim extractedText As New StringBuilder()
    For Each row In rows
        Dim line = String.Join(" ", row.OrderBy(Function(c) c.BoundingBox.Left) _
                                   .Select(Function(c) c.Contents.Trim()) _
                                   .Where(Function(text) Not String.IsNullOrWhiteSpace(text)))
        extractedText.AppendLine(line)
    Next
    Return extractedText.ToString()
End Function
$vbLabelText   $csharpLabel

rowTolerance = 2.0から始めます。 行がまだ結合される場合は、それを0.5まで下げてください。 より細かな制御のために、page.TextChunksに置き換えます。

代替案: 視覚順序での抽出

コンテンツストリーム順のみが間違っているPDFの場合:

pdf.ExtractTextFromPage(i, TextExtractionOrder.VisualOrder);
pdf.ExtractTextFromPage(i, TextExtractionOrder.VisualOrder);
pdf.ExtractTextFromPage(i, TextExtractionOrder.VisualOrder)
$vbLabelText   $csharpLabel

行が非常に近接しているPDFの場合、TextChunksアプローチは厳密な許容差をよりうまく処理します。

Curtis Chau
テクニカルライター

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

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

準備はできましたか?
Nuget ダウンロード 20,088,359 | バージョン: 2026.7 リリースされたばかり
Still Scrolling Icon

まだスクロールしていますか?

すぐに証拠が欲しいですか? PM > Install-Package IronPdf
サンプルを実行するHTML が PDF に変換されるのを確認します。