Wyodrębnianie tekstu w niewłaściwej kolejności z gęsto upakowanych tabel
Tekst wyodrębniony z gęsto upakowanych układów tabel lub formularzy wydaje się być pomieszany. Znaki z sąsiednich rzędów są przeplatane, na przykład, "Unikalny Numer 123456789" jest wyodrębniany jako "U123456789nikalny Numer".
Jest to znane ograniczenie ekstrakcji page.Lines dla układów o gęsto upakowanych elementach. page.Lines grupuje znaki z użyciem wbudowanej tolerancji pionowej, która nie jest konfigurowalna. Gdy dwa widoczne rzędy w komórce tabeli są oddalone od siebie o punkt lub dwa, grupator łączy oba rzędy w jedną logiczną linię i sortuje znaki od lewej do prawej, przeplatając je. Metoda ExtractTextFromPage(i) domyślnie używa kolejności strumienia zawartości, która może nie odpowiadać wizualnej kolejności czytania w formularzach PDF.
Rozwiązanie
Zalecane: Wyodrębnianie przy użyciu TextChunks z możliwością regulacji tolerancji
Każdy TextChunk ujawnia swoje BoundingBox, co pozwala na grupowanie według pozycji pionowej i sortowanie w każdym wierszu według pozycji poziomej:
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
Rozpocznij od rowTolerance = 2.0. Jeśli wiersze nadal się łączą, obniż to do 1.0 lub 0.5. Dla bardziej precyzyjnej kontroli, zastąp page.Characters na page.TextChunks.
Alternatywa: Wyodrębnianie w kolejności wizualnej
Dla plików PDF, w których tylko kolejność strumienia treści jest błędna:
pdf.ExtractTextFromPage(i, TextExtractionOrder.VisualOrder);
pdf.ExtractTextFromPage(i, TextExtractionOrder.VisualOrder);
pdf.ExtractTextFromPage(i, TextExtractionOrder.VisualOrder)
Dla PDF-ów z liniami, które są wizualnie bardzo blisko siebie, podejście TextChunks lepiej radzi sobie z małymi tolerancjami.

