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 结果。任何帮助将不胜感激。
可以从单个图层中获取内容,但您必须跳过几个环节才能完成。具体来说,您必须重新创建 PdfTextExtractor
和 PdfReaderContentParser
.
提供的一些逻辑
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
}
如果您特别想只使用 PdfTextExtractor
或 PdfReaderContentParser
,并询问返回的 TextRenderInfo
它所在的层,那么我不确定它会是很容易成为可能。这有很多问题:
TextRenderInfo
不存储该信息,因此您必须对其进行子类化(这是可能的)
- 您必须重写创建
TextRenderInfo
对象的逻辑。这可以通过使用 PdfTextExtractor
或 PdfReaderContentParser
- 最困难的部分是您已经在
ContentByteUtils.GetContentBytesFromContentObject
中丢失了图层信息 - 因此您需要以某种方式保留它,这会产生一系列问题。
目前我正在使用自定义 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 结果。任何帮助将不胜感激。
可以从单个图层中获取内容,但您必须跳过几个环节才能完成。具体来说,您必须重新创建 PdfTextExtractor
和 PdfReaderContentParser
.
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
}
如果您特别想只使用 PdfTextExtractor
或 PdfReaderContentParser
,并询问返回的 TextRenderInfo
它所在的层,那么我不确定它会是很容易成为可能。这有很多问题:
TextRenderInfo
不存储该信息,因此您必须对其进行子类化(这是可能的)- 您必须重写创建
TextRenderInfo
对象的逻辑。这可以通过使用PdfTextExtractor
或PdfReaderContentParser
- 最困难的部分是您已经在
ContentByteUtils.GetContentBytesFromContentObject
中丢失了图层信息 - 因此您需要以某种方式保留它,这会产生一系列问题。