首页 > 解决方案 > 如何使用 iText7 获取 PDF 的书签页码

问题描述

我使用下面的代码获取书签的页码,但是返回的页码不正确,

var names = pdfDoc.GetCatalog().GetNameTree(PdfName.Dests).GetNames();
var newestBookmark = GetBookmarks(pdfDoc.GetOutlines(false), pdfDoc, names).LastOrDefault();
private static IDictionary<string, int> GetBookmarks(PdfOutline outline, PdfDocument pdfDoc, IDictionary<string, PdfObject> names)
{
    if (outline == null)
    {
        return pdfOutlines;
    }
    var inner = outline.GetAllChildren();
    if (inner != null && inner.Count > 0)
    {
        foreach (var item in inner)
        {
            if (DateTime.TryParse(item.GetTitle(), out DateTime title))
            {                        
                pdfOutlines.Add(item.GetTitle(), pdfDoc.GetPageNumber((PdfDictionary)outline.GetDestination().GetDestinationPage(names)));
            }
            if (item.GetAllChildren() != null && item.GetAllChildren().Count > 0)
            {
                GetBookmarks(item, pdfDoc, names);
            }
        }
    }
    return pdfOutlines;
}

还有其他获取页码的方法吗?

谢谢

标签: c#pdfitext

解决方案


我建议浏览页面大纲,使用PdfOutline的子级遍历层次结构,以便递归地遍历它们。

要通过页面对象查找页码,您应该使用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 = pdfDoc.getCatalog().getNameTree(PdfName.Dests);
PdfOutline root = pdfDoc.getOutlines(false);
walkOutlines(root, destsTree.getNames(), pdfDoc);

推荐阅读