从文档大纲(书签)中获取页码
我正在使用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
。