2017-10-12 102 views
0

我正在使用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) - 但是這個功能似乎在iText7被刪除。

編輯: 我看看網實現的PdfExplicitDestination.getDestinationPage()Github(同爲java我不明白的參數傳遞給該方法的目的。如果我通過在空似乎工作的。在大綱層次結構中只使用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"); 
     }  
    } 
} 

所以我仍然試圖找出這個。

回答

1

關於大綱層次的級別,爲了遍歷整個層次結構,您必須檢查每個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

+0

非常感謝。這比我預料的更復雜! –