我正在使用PDFbox提取PDF文档中单词/字符串的坐标,并且到目前为止已成功确定单个字符的位置 . 这是迄今为止的代码,来自PDFbox doc:
package printtextlocations;
import java.io.*;
import org.apache.pdfbox.exceptions.InvalidPasswordException;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.common.PDStream;
import org.apache.pdfbox.util.PDFTextStripper;
import org.apache.pdfbox.util.TextPosition;
import java.io.IOException;
import java.util.List;
public class PrintTextLocations extends PDFTextStripper {
public PrintTextLocations() throws IOException {
super.setSortByPosition(true);
}
public static void main(String[] args) throws Exception {
PDDocument document = null;
try {
File input = new File("C:\\path\\to\\PDF.pdf");
document = PDDocument.load(input);
if (document.isEncrypted()) {
try {
document.decrypt("");
} catch (InvalidPasswordException e) {
System.err.println("Error: Document is encrypted with a password.");
System.exit(1);
}
}
PrintTextLocations printer = new PrintTextLocations();
List allPages = document.getDocumentCatalog().getAllPages();
for (int i = 0; i < allPages.size(); i++) {
PDPage page = (PDPage) allPages.get(i);
System.out.println("Processing page: " + i);
PDStream contents = page.getContents();
if (contents != null) {
printer.processStream(page, page.findResources(), page.getContents().getStream());
}
}
} finally {
if (document != null) {
document.close();
}
}
}
/**
* @param text The text to be processed
*/
@Override /* this is questionable, not sure if needed... */
protected void processTextPosition(TextPosition text) {
System.out.println("String[" + text.getXDirAdj() + ","
+ text.getYDirAdj() + " fs=" + text.getFontSize() + " xscale="
+ text.getXScale() + " height=" + text.getHeightDir() + " space="
+ text.getWidthOfSpace() + " width="
+ text.getWidthDirAdj() + "]" + text.getCharacter());
}
}
这会产生一系列包含每个字符位置的行,包括空格,如下所示:
String[202.5604,41.880127 fs=1.0 xscale=13.98 height=9.68814 space=3.8864403 width=9.324661]P
其中'P'是角色 . 我无法在PDFbox中找到一个函数来查找单词,而且我对Java不熟悉,能够准确地将这些字符连接成单词以进行搜索,即使这些空格也包含在内 . 有没有其他人处于类似的情况,如果是这样,你是如何接近它的?我真的只需要单词中第一个字符的坐标,以便简化部分,但是我将如何匹配一个字符串与那种输出相比是超出我的 .
3 回答
PDFBox中没有允许您自动提取单词的功能 . 我正在努力提取数据以将其收集到块中,这是我的过程:
我提取文档的所有字符(称为字形)并将它们存储在列表中 .
我对每个字形的坐标进行分析,循环遍历列表 . 如果它们重叠(如果当前字形的顶部包含在当前字形的前面/底部的顶部和底部之间,则包含在前一个字体的顶部和底部之间),我将它添加到同一行 .
此时,我已经提取了文档的不同行(注意,如果您的文档是多列,则表达“行”表示垂直重叠的所有字形,即具有相同字符的所有列的文本垂直坐标) .
然后,您可以将当前字形的左坐标与前一个字体的右坐标进行比较,以确定它们是否属于同一个字(PDFTextStripper类提供了一个getSpacingTolerance()方法,根据试验和错误,“正常”空间的值 . 如果右坐标和左坐标之间的差异低于此值,则两个字形属于同一个字 .
我将这种方法应用到我的工作中并且效果很好 .
基于最初的想法,这里是PDFBox 2的文本搜索版本 . 代码本身很粗糙,但很简单 . 它应该让你很快开始 .
看看这个,我想这就是你需要的 .
https://jackson-brain.com/using-pdfbox-to-locate-text-coordinates-within-a-pdf-in-java/
这是代码:
依赖关系:
您可以通过在命令行上键入来运行它:
输出类似于: