此选项不会立即包含在 iTextSharp 发行版中,但很容易实现。在下文中,我使用 iText (Java) 类、接口和方法名称,因为我更熟悉 Java。它们应该很容易翻译成 iTextSharp (C#) 名称。
如果您使用LocationTextExtractionStrategy,您可以使用它的后验TextChunkFilter 机制,而不是您链接到的示例中使用的先验FilteredRenderListener 机制。该机制已在 5.3.3 版本中引入。
为此,您首先使用LocationTextExtractionStrategy 解析整个页面内容,而不应用任何FilteredRenderListener 过滤。这使得策略对象为包含相关基线段的页面上的所有 PDF 文本对象收集 TextChunk 对象。
然后您使用 TextChunkFilter 参数调用策略的 getResultantText 重载(而不是常规的无参数重载):
public String getResultantText(TextChunkFilter chunkFilter)
您为每个表格单元格使用不同的TextChunkFilter 实例来调用它。你必须实现这个过滤器接口,它并不难,因为它只定义了一个方法:
public static interface TextChunkFilter
{
/**
* @param textChunk the chunk to check
* @return true if the chunk should be allowed
*/
public boolean accept(TextChunk textChunk);
}
因此,给定单元格的过滤器的接受方法必须测试有问题的文本块是否在您的单元格内。
(除了每个单元格的单独实例,您当然也可以创建一个实例,其参数(即单元格坐标)可以在 getResultantText 调用之间更改。)
PS: 正如 OP 所说,这个 TextChunkFilter 尚未移植到 iTextSharp。不过,这样做应该不难,只需一个小界面和一种方法即可添加到策略中。
PPS:在评论sschuberth问
在使用getResultantText() 时,您是否仍然调用PdfTextExtractor.getTextFromPage(),或者它会以某种方式取代该调用?如果是这样,您如何指定要提取到的页面?
其实PdfTextExtractor.getTextFromPage()内部已经使用了无参数getResultantText()重载:
public static String getTextFromPage(PdfReader reader, int pageNumber, TextExtractionStrategy strategy, Map<String, ContentOperator> additionalContentOperators) throws IOException
{
PdfReaderContentParser parser = new PdfReaderContentParser(reader);
return parser.processContent(pageNumber, strategy, additionalContentOperators).getResultantText();
}
要使用TextChunkFilter,您可以简单地构建一个类似的便捷方法,例如
public static String getTextFromPage(PdfReader reader, int pageNumber, LocationTextExtractionStrategy strategy, Map<String, ContentOperator> additionalContentOperators, TextChunkFilter chunkFilter) throws IOException
{
PdfReaderContentParser parser = new PdfReaderContentParser(reader);
return parser.processContent(pageNumber, strategy, additionalContentOperators).getResultantText(chunkFilter);
}
但是,在当前的上下文中,我们只想解析页面内容一次并应用多个过滤器,每个单元格一个过滤器,我们可以将其概括为:
public static List<String> getTextFromPage(PdfReader reader, int pageNumber, LocationTextExtractionStrategy strategy, Map<String, ContentOperator> additionalContentOperators, Iterable<TextChunkFilter> chunkFilters) throws IOException
{
PdfReaderContentParser parser = new PdfReaderContentParser(reader);
parser.processContent(pageNumber, strategy, additionalContentOperators)
List<String> result = new ArrayList<>();
for (TextChunkFilter chunkFilter : chunkFilters)
{
result.add(strategy).getResultantText(chunkFilter);
}
return result;
}
(您可以通过使用 Java 8 集合流而不是老式的 for 循环来使这个看起来更漂亮。)