从挤得很紧的表格中提取文本时顺序错乱

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

从紧密排列的表格或表单布局中提取的文本出现顺序错乱。 来自相邻行的字符混杂在一起,例如,"Unique Number 123456789"被提取为"U123456789nique Number"。

这是一个已知的从密集布局中提取page.Lines的限制。 page.Lines使用内置的不可配置的垂直容差对字符进行分组。 当表格单元格中的两个可见行仅相距一点或两点时,分组合并两个行为一条逻辑线,从左到右排序字符,并进行交错。 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 对物联网 (IoT) 有浓厚的兴趣,探索将硬件和软件集成的新方法。在空闲时间,他喜欢玩游戏和构建 Discord 机器人,将他对技术的热爱与创造力相结合。

准备开始了吗?
Nuget 下载 20,088,359 | 版本: 2026.7 刚刚发布
Still Scrolling Icon

还在滚动吗?

想快速获得证据? PM > Install-Package IronPdf
运行示例看着你的HTML代码变成PDF文件。