返回
PDFBox 2.0.2 提取字体新方法: 文本定位与资源访问
java
2025-01-01 11:11:13
PDFBox 2.0.2 中提取字体
在处理PDF文档时,有时需要提取其中使用的字体。过去版本 PDFBox 中提供的 getFonts()
方法在 2.0.2 版本中已被移除,这导致许多开发者需要寻找新的方法来提取字体信息。本文探讨几种方法,并提供代码示例。
文本定位和字体关联
一种常用策略是结合文本提取和字体分析来获取每个文本片段对应的字体。PDFBox 的 PDFTextStripper
类能有效地提取文本,并且其内部逻辑会跟踪字体状态变化。我们可以扩展此类,从而捕捉这些变化,并关联文本和字体。
步骤:
- 创建自定义的
PDFTextStripper
子类。 - 覆盖
processTextPosition
方法,此方法会在每个文本位置被调用。 - 在方法内,将当前字体与提取的文本关联。
- 创建一个存储文本和字体的 Map。
代码示例:
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.font.PDFont;
import org.apache.pdfbox.text.PDFTextStripper;
import org.apache.pdfbox.text.TextPosition;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
public class FontExtractor extends PDFTextStripper {
private final Map<String, PDFont> textFonts = new HashMap<>();
public FontExtractor() throws IOException {
}
@Override
protected void writeString(String string, java.util.List<TextPosition> textPositions) throws IOException {
super.writeString(string,textPositions);
PDFont currentFont = textPositions.get(0).getFont();
textFonts.put(string, currentFont);
}
public Map<String, PDFont> getTextFonts() {
return textFonts;
}
public static void main(String[] args) throws IOException {
try (PDDocument document = PDDocument.load(new java.io.File("your_document.pdf"))) { // Replace with your PDF file
FontExtractor extractor = new FontExtractor();
String text = extractor.getText(document);
Map<String, PDFont> fonts = extractor.getTextFonts();
fonts.forEach((key,value) -> System.out.println( "Text: " + key + ", Font: " + value.getName()));
}
}
}
操作说明:
- 将代码保存为
FontExtractor.java
文件。 - 将 "your_document.pdf" 替换成您的PDF文件路径。
- 编译并执行该Java程序,程序输出每个文本及其关联的字体信息。
注意事项:
- 这段代码依赖
textPositions
中的第一项的字体,对于复杂的文本,可能有其他文本也需要记录字体。
使用 PDResources 获取字体信息
虽然文档的 getFonts()
方法被删除, 但我们可以通过访问 PDPage
的资源,来获取文档中使用的字体资源信息。该方法提供了整个文档使用的字体的概要,但不直接对应具体的文本位置。
步骤:
- 遍历
PDDocument
的每一页。 - 获取页面的
PDResources
对象。 - 利用
getResources
获取PDFont
列表 - 遍历这些字体,进行需要的操作。
代码示例:
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDResources;
import org.apache.pdfbox.pdmodel.font.PDFont;
import org.apache.pdfbox.cos.COSName;
import java.io.IOException;
import java.util.Map;
public class ResourceFontExtractor {
public static void main(String[] args) {
try (PDDocument document = PDDocument.load(new java.io.File("your_document.pdf"))) { // Replace with your PDF file
for (PDPage page : document.getPages()) {
PDResources resources = page.getResources();
if(resources !=null)
{
Map<COSName,org.apache.pdfbox.pdmodel.font.PDFont> fontMap= resources.getFonts();
fontMap.forEach((key, value)-> System.out.println(" Font name: "+ value.getName()));
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
操作说明:
- 将代码保存为
ResourceFontExtractor.java
文件。 - 将 “your_document.pdf" 替换成您的PDF文件路径。
- 编译并执行该Java程序。它会打印出每页使用的字体名称。
安全建议:
- 加载不受信任的 PDF 文件时,需要谨慎对待。可以使用沙箱或者其他的安全措施。
- 在处理文档之前,应验证输入的有效性,避免恶意操作引发异常。
总而言之,虽然PDFBox的API改变了,通过继承PDFTextStripper
或是直接访问PDResources
都可以达到字体提取的目标。
选择哪个方案,则取决于您具体的需求。希望这两个方法对你有帮助。