Java PDFBox列出页面的所有命名目标
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java PDFBox列出页面的所有命名目标相关的知识,希望对你有一定的参考价值。
对于我的Java项目,我需要列出PDF页面的所有命名目标。
PDF及其命名目的地是用LaTeX(使用hypertarget command)创建的,例如:如下:
documentclass[12pt]{article}
usepackage{hyperref}
egin{document}
hypertarget{myImportantString}{} % the anchor/named destination to be extracted "myImportantString"
Empty example page
end{document}
如何使用PDFBox库版本2.0.11提取此PDF文档的特定页面的所有命名目标?
我在互联网或PDFBox examples找不到任何有关此问题的工作代码。这是我目前的(缩小的)代码:
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotation;
import java.io.File;
import java.util.List;
public class ExtractNamedDests {
public static void main(String[] args) {
try {
int c = 1;
PDDocument document = PDDocument.load(new File("<path to PDF file>"));
for (PDPage page : document.getPages()) {
System.out.println("Page " + c + ":");
// named destinations seem to be no type of annotations since the list is always empty:
List<PDAnnotation> annotations = page.getAnnotations();
System.out.println(" Count annotations: " + annotations.size());
// How to extract named destinations??
}
}catch(Exception e){
e.printStackTrace();
}
}
}
在这个例子中,我想从Java中的页面中提取字符串“myImportantString”。
编辑:这是example PDF file。我使用PDFBox版本2.0.11。
答案
我在Tilman Hausherr的帮助下找到了解决方案。它使用了他在评论中建议的代码。
方法getAllNamedDestinations()
返回文档中所有已命名目标的映射(不是注释),其中包含名称和目标。命名目标可以深深嵌套在文档中。因此,方法traverseKids()
递归地查找所有嵌套的命名目标。
public static Map<String, PDPageDestination> getAllNamedDestinations(PDDocument document){
Map<String, PDPageDestination> namedDestinations = new HashMap<>(10);
// get catalog
PDDocumentCatalog documentCatalog = document.getDocumentCatalog();
PDDocumentNameDictionary names = documentCatalog.getNames();
if(names == null)
return namedDestinations;
PDDestinationNameTreeNode dests = names.getDests();
try {
if (dests.getNames() != null)
namedDestinations.putAll(dests.getNames());
} catch (Exception e){ e.printStackTrace(); }
List<PDNameTreeNode<PDPageDestination>> kids = dests.getKids();
traverseKids(kids, namedDestinations);
return namedDestinations;
}
private static void traverseKids(List<PDNameTreeNode<PDPageDestination>> kids, Map<String, PDPageDestination> namedDestinations){
if(kids == null)
return;
try {
for(PDNameTreeNode<PDPageDestination> kid : kids){
if(kid.getNames() != null){
try {
namedDestinations.putAll(kid.getNames());
} catch (Exception e){ System.out.println("INFO: Duplicate named destinations in document."); e.printStackTrace(); }
}
if (kid.getKids() != null)
traverseKids(kid.getKids(), namedDestinations);
}
} catch (Exception e){
e.printStackTrace();
}
}
以上是关于Java PDFBox列出页面的所有命名目标的主要内容,如果未能解决你的问题,请参考以下文章
访问我加载的 .pdf 页面(使用 pdfbox)(我正在使用 RPG)