使用 iText7 从 PDF 中提取文本。如何提高其性能?

2023-12-10

目前,我使用此代码从矩形(区域)中提取文本。

public static class ReaderExtensions
{
    public static string ExtractText(this PdfPage page, Rectangle rect)
    {
        var filter = new IEventFilter[1];
        filter[0] = new TextRegionEventFilter(rect);
        var filteredTextEventListener = new FilteredTextEventListener(new LocationTextExtractionStrategy(), filter);
        var str = PdfTextExtractor.GetTextFromPage(page, filteredTextEventListener);
        return str;
    }
}

它有效,但我不知道这是否是最好的方法。

另外,我想知道 iText 团队是否可以改进 GetTextFromPage 以提高其性能,因为我正在处理大型 PDF 中的数百个页面,并且使用我当前的配置通常需要 10 多分钟才能完成。

EDIT:

从评论来看:看起来iText可以一次提取同一页面上多个矩形的文本,这可以提高性能(批量操作往往更高效),但是如何呢?

更多细节!

我的目标是从多页 PDF 中提取数据。每个页面都有相同的布局:包含行和列的表格。

目前,我正在使用上面的方法来提取每个矩形的文本。但是,如您所见,提取不是批量的。一次只是一个矩形。如何一次性提取页面的所有矩形?


正如评论中已经提到的,我很惊讶地发现 iText 7LocationTextExtractionStrategy不再包含类似于 iText 5 的内容LocationTextExtractionStrategy method GetResultantText(TextChunkFilter)。这将允许您解析一次页面并从任意页面区域中的文本片段中提取文本。

但有可能恢复该功能。一种选择是将其添加到LocationTextExtractionStrategy。不过,这将是一个很长的答案。所以我使用了另一个选择:我使用现有的LocationTextExtractionStrategy,并且仅仅为了GetResultantText调用我操纵策略的文本块的底层列表。而不是通用的TextChunkFilter界面我将过滤限制为手头的标准,即按矩形区域进行过滤。

public static class ReaderExtensions
{
    public static string[] ExtractText(this PdfPage page, params Rectangle[] rects)
    {
        var textEventListener = new LocationTextExtractionStrategy();
        PdfTextExtractor.GetTextFromPage(page, textEventListener);
        string[] result = new string[rects.Length];
        for (int i = 0; i < result.Length; i++)
        {
            result[i] = textEventListener.GetResultantText(rects[i]);
        }
        return result;
    }

    public static String GetResultantText(this LocationTextExtractionStrategy strategy, Rectangle rect)
    {
        IList<TextChunk> locationalResult = (IList<TextChunk>)locationalResultField.GetValue(strategy);
        List<TextChunk> nonMatching = new List<TextChunk>();
        foreach (TextChunk chunk in locationalResult)
        {
            ITextChunkLocation location = chunk.GetLocation();
            Vector start = location.GetStartLocation();
            Vector end = location.GetEndLocation();
            if (!rect.IntersectsLine(start.Get(Vector.I1), start.Get(Vector.I2), end.Get(Vector.I1), end.Get(Vector.I2)))
            {
                nonMatching.Add(chunk);
            }
        }
        nonMatching.ForEach(c => locationalResult.Remove(c));
        try
        {
            return strategy.GetResultantText();
        }
        finally
        {
            nonMatching.ForEach(c => locationalResult.Add(c));
        }
    }

    static FieldInfo locationalResultField = typeof(LocationTextExtractionStrategy).GetField("locationalResult", BindingFlags.NonPublic | BindingFlags.Instance);
}

中央扩展是LocationTextExtractionStrategy扩展需要一个LocationTextExtractionStrategy它已经包含页面中的信息,将这些信息限制为给定矩形中的信息,提取文本,并将信息返回到先前的状态。这需要一些反思;我希望这对你来说没问题。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 iText7 从 PDF 中提取文本。如何提高其性能? 的相关文章

随机推荐