2017-10-12 14 views
0

私はitext7ライブラリを使用していくつかの既存のPDFを操作しています。何らかの理由で、アウトラインからページ番号を取得できません。私はどうにかしてPdfDestinationから取得するべきだと思うが、そのサブクラスのどのマッチングメソッドも見つけることができない。 iText5で文書の概要(ブックマーク)からページ番号を取得

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 
} 

私は、「ページ」のエントリを含む辞書のリストを返しSimpleBookmark.GetBookmark(reader)を使用 - しかし、この機能はiText7で削除されているようです。

編集: 私はjavaのために同じ(GithubPdfExplicitDestination.getDestinationPage()の純実装を見ていた私は、このメソッドのパラメータの目的を理解していない私はnullを渡すと、上で動作するようです。 pdfsは、ToString()を使用してアウトライン階層内の1つのレベルのみを使用します。つまり、ゼロインデックス付きのページ番号を文字列として返すことを意味します(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#ではいくつかの大文字と小文字の変更を除いて同様でなければなりません。Mapの場合はIDictionaryとなります。

+0

ありがとうございます。それは私が予想していた以上に複雑でした! –

関連する問題