iTextSharp 从单层 PDF 读取文本

iTextSharp Read Text From Single Layer of PDF

目前我正在使用自定义 LocationTextExtractionStrategy 从 returns TextRenderInfo[] 的 PDF 中提取文本。我希望能够确定 TextRenderInfo 对象(或 PDFString,TextRenderInfo 的子对象)是否出现在特定层中。我不确定这是否可能。要获取 PDF 中的图层,我使用:

Dictionary<string,PdfLayer> layers;
using (var pdfReader = new PdfReader(src))
{
    var newSrc = Path.Combine(["new file location"]);
    using (var stream = new FileStream(newSrc, FileMode.Create))
    {       
        PdfStamper stamper = new PdfStamper(pdfReader, stream);
        layers = stamper.GetPdfLayers();
        stamper.Close();
    }
    pdfReader.Close();
    src = newSrc;
}

要提取文本,我使用的是:

var textExtractor = new TextExtractionStrategy();
PdfTextExtractor.GetTextFromPage(pdfReader, pdfPageNum,textExtractor);
List<TextRenderInfo> results = textExtractor.Results;

有什么方法可以检查第一个代码片段中获得的图层中是否存在各个 TextRenderInfo 结果。任何帮助将不胜感激。

可以从单个图层中获取内容,但您必须跳过几个环节才能完成。具体来说,您必须重新创建 PdfTextExtractorPdfReaderContentParser.

提供的一些逻辑
public static String GetText(PdfReader reader, int pageNumber, int streamNumber) {
    var strategy = new LocationTextExtractionStrategy();
    var processor = new PdfContentStreamProcessor(strategy);

    var resourcesDic = pageDic.GetAsDict(PdfName.RESOURCES);

    // assuming you still need to extract the page bytes
    byte[] contents = GetContentBytesForPageStream(reader, pageNumber, streamNumber);

    processor.ProcessContent(contents, resourcesDic);
    return strategy.GetResultantText();
}

public static byte[] GetContentBytesForPageStream(PdfReader reader, int pageNumber, int streamNumber) {
    PdfDictionary pageDictionary = reader.GetPageN(pageNum);
    PdfObject contentObject = pageDictionary.Get(PdfName.CONTENTS);
    if (contentObject == null)
        return new byte[0];

    byte[] contentBytes = GetContentBytesFromContentObject(contentObject, streamNumber);
    return contentBytes;
}

public static byte[] GetContentBytesFromContentObject(PdfObject contentObject, int streamNumber) {
    // copy-paste logic from
    // ContentByteUtils.GetContentBytesFromContentObject(contentObject);
    // but in case PdfObject.ARRAY: only select the streamNumber you require
}

如果您特别想只使用 PdfTextExtractorPdfReaderContentParser,并询问返回的 TextRenderInfo 它所在的层,那么我不确定它会是很容易成为可能。这有很多问题:

  • TextRenderInfo 不存储该信息,因此您必须对其进行子类化(这是可能的)
  • 您必须重写创建 TextRenderInfo 对象的逻辑。这可以通过使用 PdfTextExtractorPdfReaderContentParser
  • 最困难的部分是您已经在 ContentByteUtils.GetContentBytesFromContentObject 中丢失了图层信息 - 因此您需要以某种方式保留它,这会产生一系列问题。