我正在使用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"输入 - 但这个功能似乎已在iText7中删除。
修改 我查看PdfExplicitDestination.getDestinationPage()上Github的网络实施情况({3}}也一样。我不了解此方法参数的用途。如果我传入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");
}
}
}
所以我仍然想弄清楚这一点。
答案 0 :(得分:2)
关于大纲层次结构的级别,为了遍历整个层次结构,您必须检查每个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
。