如何用PDFBox获取PDF选中文本的字体信息?getResources返回null求助
解决PDFTextStripperByArea获取区域字体信息的问题
哦,这个坑我之前踩过!PDFTextStripperByArea的getResources()方法确实经常返回null,因为它的核心定位是提取指定区域的文本内容,并没有为区域资源查询做专门的设计。不过别担心,我们可以通过自定义子类的方式绕开这个限制,直接拿到目标文本的字体信息,下面是具体的实现思路和代码:
方案一:自定义PDFTextStripperByArea子类,记录文本位置与字体信息
我们可以重写processTextPosition方法,在处理每个文本片段时,判断它是否落在我们定义的区域内,同时记录对应的TextPosition对象——这个对象里包含了完整的字体、字号等信息。
import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDPage; import org.apache.pdfbox.text.PDFTextStripperByArea; import org.apache.pdfbox.text.TextPosition; import java.awt.geom.Rectangle2D; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; public class RegionTextWithFontStripper extends PDFTextStripperByArea { // 存储每个区域对应的所有TextPosition实例 private final Map<String, List<TextPosition>> regionTextPositions = new HashMap<>(); public RegionTextWithFontStripper() throws IOException { super(); setSortByPosition(true); // 保持文本顺序 } @Override protected void processTextPosition(TextPosition text) { super.processTextPosition(text); // 遍历所有已定义的区域,判断当前文本是否在区域内 for (String regionName : getRegions().keySet()) { Rectangle2D regionRect = getRegion(regionName); // 注意PDFBox的坐标原点在页面左下角,确保你的区域坐标是正确的 if (regionRect.contains(text.getX(), text.getY())) { regionTextPositions.computeIfAbsent(regionName, k -> new ArrayList<>()).add(text); } } } // 获取指定区域的所有文本位置信息(包含字体) public List<TextPosition> getTextPositionsForRegion(String regionName) { return regionTextPositions.getOrDefault(regionName, Collections.emptyList()); } }
使用示例
try (PDDocument document = PDDocument.load(new File("your-file.pdf"))) { PDPage page = document.getPage(0); // 假设处理第一页 RegionTextWithFontStripper stripper = new RegionTextWithFontStripper(); // 添加你的目标区域 Rectangle2D rect = new Rectangle2D.Double(96, 150, 101, 11); stripper.addRegion("selectedText", rect); stripper.extractRegions(page); // 获取区域内的所有TextPosition List<TextPosition> textPositions = stripper.getTextPositionsForRegion("selectedText"); for (TextPosition text : textPositions) { // 提取字体名称、字号等信息 String fontName = text.getFont().getName(); float fontSize = text.getFontSize(); String content = text.getUnicode(); System.out.printf("文本:%s,字体:%s,字号:%.1f%n", content, fontName, fontSize); } } catch (IOException e) { e.printStackTrace(); }
注意事项
- 坐标校验:PDFBox的坐标原点在页面左下角,如果你是从其他工具(比如PDF阅读器)获取的坐标,可能需要转换y轴(页面高度 - 原y坐标)才能匹配正确区域。
- 文本片段:一个完整的单词可能被拆分成多个
TextPosition实例,你可能需要根据位置信息合并它们,再统一处理字体。
内容的提问来源于stack exchange,提问作者swarupn
相关产品推荐
相关产品推荐

