我正在使用 itext7 库来操作一些现有的 PDF。由于某种原因,我无法从大纲中获取页码。我想我应该以某种方式从Pdf目的地 http://itextsupport.com/apidocs/itext7/latest/com/itextpdf/kernel/pdf/navigation/PdfDestination.html但在其任何子类中找不到任何匹配的方法。
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”条目的字典列表 - 但此功能似乎已在 iText7 中删除。
Edit:我查看了 Net 实现PdfExplicitDestination.getDestinationPage() http://itextsupport.com/apidocs/itext7/latest/com/itextpdf/kernel/pdf/navigation/PdfExplicitDestination.html#getDestinationPage-java.util.Map- on Github https://github.com/itext/itext7-dotnet/blob/develop/itext/itext.kernel/itext/kernel/pdf/navigation/PdfExplicitDestination.cs(同样适用于java https://github.com/itext/itext7/blob/develop/kernel/src/main/java/com/itextpdf/kernel/pdf/navigation/PdfExplicitDestination.java。我不明白该方法的参数的用途。如果我传入 null,它似乎适用于使用 ToString() 在大纲层次结构中仅使用一级的 pdf。我所说的工作是指它将零索引页码作为字符串返回。对于 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<String, PdfObject> 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
.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)