从文档大纲(书签)中获取页码

我正在使用itext7库来操作一些现有的PDF。 出于某种原因,我无法从大纲中获取页码。 我想我应该以某种方式从PdfDestination中获取它,但在其任何子类中都找不到任何匹配的方法。

PdfDocument pdfDoc = new PdfDocument(new PdfReader("example.pdf")); var root = pdfDoc.GetOutlines(false); foreach (PdfOutline ol in root.GetAllChildren()) { Console.WriteLine(ol.GetTitle()); PdfDestination d = ol.GetDestination(); // how to get the page number from the destination object } 

在iText5中,我使用了SimpleBookmark.GetBookmark(reader) ,它返回了包含“Page”条目的词典列表 – 但这个function似乎已在iText7中删除了。

编辑:我看了一下Github上的PdfExplicitDestination.getDestinationPage()的Net实现(对于java来说是一样的。我不明白这个方法的参数的用途。如果我传入null,它似乎只适用于pdf使用ToString()在大纲层次结构中使用一个级别。通过工作我的意思是它将零索引页码作为字符串返回。对于PDF代码,它找不到页码(对于第一级别)。

 PdfDocument pdfDoc = new PdfDocument(new PdfReader("example.pdf")); var root = pdfDoc.GetOutlines(); foreach (PdfOutline ol in root.GetAllChildren()) { Console.WriteLine(ol.GetTitle()); var d = ol.GetDestination(); if (d is PdfExplicitDestination) { string PageNoStr = d.GetDestinationPage(null).ToString(); // this is the content of the method (less the ToString() //string PageNoStr = ((PdfArray)d.GetPdfObject()).Get(0).ToString(); int pageNo; if (Int32.TryParse(PageNoStr, out pageNo)) { Console.WriteLine("Page is " + pageNo); } else { Console.WriteLine("Error page"); } } } 

所以我仍然想弄明白这一点。

关于大纲层次结构的级别,为了遍历整个层次结构,您必须检查每个PdfOutline的子级并递归遍历它们。

令您感到困惑的名称参数是负责解析命名目标的参数,这通常是正确获取页码所必需的,因为您的PDF文档可能包含显式目标和命名目标。 要获取名称映射,可以使用pdfDocument.getCatalog().getNameTree(PdfName.Dests).getNames() ;

要通过页面对象查找页码,您应该使用pdfDocument.getPageNumber(PdfDictionary)

总的来说,遍历轮廓的方法可能如下所示:

 void walkOutlines(PdfOutline outline, Map names, PdfDocument pdfDocument) { if (outline.getDestination() != null) { System.out.println(outline.getTitle() + ": page " + pdfDocument.getPageNumber((PdfDictionary) outline.getDestination().getDestinationPage(names))); } for (PdfOutline child : outline.getAllChildren()) { walkOutlines(child, names, pdfDocument); } } 

并且调用方法遍历大纲根的主要入口点:

 PdfNameTree destsTree = pdfDocument.getCatalog().getNameTree(PdfName.Dests); PdfOutline root = pdfDocument.getOutlines(false); walkOutlines(root, destsTree.getNames(), pdfDocument); 

请注意,代码示例适用于Java,但在C#中应该类似,除了一些大小写更改和IDictionary如果是Map