iTextSharp从PDF的单层读取文本

时间:2018-03-13 17:45:01

标签: pdf text itext layer extraction

目前我正在使用自定义LocationTextExtractionStrategy从PDF中提取返回TextRenderInfo []的文本。我希望能够确定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结果是否存在于第一个代码段中获得的图层中。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:2)

可以从单个图层获取内容,但是您必须跳过几个箍才能解决问题。具体而言,您必须重新创建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询问其已启用的图层,那么我就是&#39;我不确定它是否容易实现。这有很多问题:

  • TextRenderInfo不存储该信息,因此您必须将其子类化(这是可能的)
  • 您必须重写创建TextRenderInfo对象的逻辑。通过为IContentOperator或{注册所有文本运算符(TjTJ'")的自定义PdfTextExtractor对象,可以实现此目的{1}}
  • 最难的部分是你已经丢失了PdfReaderContentParser中的图层信息 - 所以你需要以某种方式保留它,这会产生一系列问题。
相关问题