Extracción de texto desordenada de tablas compactas
El texto extraído de tablas o diseños de formularios compactos aparece desordenado. Caracteres de filas adyacentes se entrelazan, por ejemplo, "Número único 123456789" se extrae como "U123456789nique Number".
Esta es una limitación conocida de la extracción de page.Lines para diseños densamente empaquetados. page.Lines agrupa caracteres utilizando una tolerancia vertical incorporada que no es configurable. Cuando dos filas visibles en una celda de tabla están solo a un punto o dos de distancia, el agrupador colapsa ambas filas en una línea lógica y ordena los caracteres de izquierda a derecha, entrelazándolos. El método ExtractTextFromPage(i) utiliza por defecto el orden de flujo de contenido, el cual puede no coincidir con el orden de lectura visual en formularios PDF.
Solución
Recomendado: Extraer usando TextChunks con una tolerancia ajustable
Cada TextChunk expone su BoundingBox, lo que permite agrupar por posición vertical y ordenar dentro de cada fila por posición horizontal:
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
Comienza con rowTolerance = 2.0. Si las filas aún se fusionan, redúcelo a 1.0 o 0.5. Para un control más fino, sustituye page.Characters por page.TextChunks.
Alternativa: Extracción en orden visual
Para PDFs donde solo el orden de flujo de contenido está mal:
pdf.ExtractTextFromPage(i, TextExtractionOrder.VisualOrder);
pdf.ExtractTextFromPage(i, TextExtractionOrder.VisualOrder);
pdf.ExtractTextFromPage(i, TextExtractionOrder.VisualOrder)
Para PDFs con filas que están visualmente muy juntas, el enfoque TextChunks maneja mejor las tolerancias ajustadas.

