Java 如何在使用PDFBox从PDF提取数据时用单词替换空格
我想用一个词替换任何空列;例如,在提取Pdf数据时使用单词BLK 下表是预期表和实际结果的示例 原始表格Java 如何在使用PDFBox从PDF提取数据时用单词替换空格,java,pdf,pdfbox,Java,Pdf,Pdfbox,我想用一个词替换任何空列;例如,在提取Pdf数据时使用单词BLK 下表是预期表和实际结果的示例 原始表格 +--------------------------------------+ |# |NAME |TEL |GENDER | |---------------------------|----------| |1 |JOHN |096587498 |M | |2 |VILLA | |F
+--------------------------------------+
|# |NAME |TEL |GENDER |
|---------------------------|----------|
|1 |JOHN |096587498 |M |
|2 |VILLA | |F |
+--------------------------------------+
预期结果
# NAME TEL GENDER
1 JOHN 096587498 M
2 VILLA BLK F
# NAME TEL GENDER
1 JOHN 096587498 M
2 VILLA F
实际结果
# NAME TEL GENDER
1 JOHN 096587498 M
2 VILLA BLK F
# NAME TEL GENDER
1 JOHN 096587498 M
2 VILLA F
实际结果来自类PDFTextStripper
捕获pdf
PDFTextStripper看不到PDF中的图形行,它只看到文本字符。因此,在您的第2行中,可以看到“2”、“Villa”和“F”之间有间隙。因此,单凭这门课,你不会得到你想要的 通常,使用PDFBox可以使用以下选项:
- 您可以首先尝试通过解析页面的矢量图形指令来识别PDF中的表格单元格区域,然后逐个单元格提取文本单元格
为此提供了概念证明。注意:这个答案集中在该问题的OP提供的示例文档上。特别是,它期望线被绘制为薄填充矩形;对于一般解决方案,需要扩展收集表行的代码,以便识别以其他方式绘制的行
这种方法显然需要将表的行和列按行(或者按扩展,或者按背景色或类似的方式)划分;情况并非总是如此
对于示例文档,代码是开箱即用的:
(test[A1]# [A2]姓名 [A3]电话 [A4]性别 [B1]1 [B2]约翰 [B3]096875959 [B4]M [C1]2 [C2]别墅 [C3] [C4]F
)testExtractBoxedTextStestWPhroma的输出
- 您可以提取试图反映PDF布局的文本。如果您知道相关表格的总体布局(n列从这里到那里…),则可以导出表格单元格内容
为布局感知文本提取提供概念证明。注意,代码是基于PDFBox 1.8.x的,可能需要进行一些修改
这种方法需要了解表列布局;这并不总是被给予的
对于示例文档,代码是开箱即用的:
(test#姓名电话性别 1约翰096875959米 F别墅2号
testExtractTestWPhroma的输出
- 对于标记的PDF,您可以尝试提取文本,包括反映表结构的标记(如果标记正确) 当您的示例文档被标记时,我将在下面展示一个快速的概念证明 这种方法要求PDF正确标记;情况并非总是如此
PDDocument document = PDDocument.load(SOURCE);
Map<PDPage, Map<Integer, PDMarkedContent>> markedContents = new HashMap<>();
for (PDPage page : document.getPages()) {
PDFMarkedContentExtractor extractor = new PDFMarkedContentExtractor();
extractor.processPage(page);
Map<Integer, PDMarkedContent> theseMarkedContents = new HashMap<>();
markedContents.put(page, theseMarkedContents);
for (PDMarkedContent markedContent : extractor.getMarkedContents()) {
theseMarkedContents.put(markedContent.getMCID(), markedContent);
}
}
PDStructureNode root = document.getDocumentCatalog().getStructureTreeRoot();
showStructure(root, markedContents);
(辅助方法)
示例PDF的输出
是
#
名称
电话
性别
1.
约翰
096875959
M
2.
别墅
F
您可以识别空单元格:
<TD>
<P>
</P>
</TD>
此概念验证提取到标准输出。显然,您可以选择在字符串生成器或流中收集数据,也可以将
数据立即填充到自定义结构中,毕竟它们已经在单元格中分开了
小心:这只是概念的证明。其中,代码输出如下数据:
System.out.printf(“?%s\n”,…)代码>,可能需要一些特定的处理。此外,可能未充分考虑其他边界条件。(实际上,我实现它只是为了正确提取示例PDF的内容。)不幸的是,您没有共享有问题的PDF,因此我无法判断它是否已标记。你能分享它进行分析吗?@mkl你可以在这里访问示例文件。好啊我会试着调查一下。不过,最有可能在周一之前。(我快速查看了一下。您的PDF已被标记。如果它代表您的源PDF,则提取标记的文本将对您有所帮助。)ExtractMarkedContent已使用当前的PDFBox 3.0.0开发分支快照进行了测试。不过,在当前的2.0.x版本中也应该可以使用。非常感谢您的努力。我将尝试这些方法,看看它们是否能解决我的问题。非常感谢:)。