2017-10-12 4 views
0

일부 기존 PDF를 조작하기 위해 itext7 라이브러리를 사용하고 있습니다. 어떤 이유로, 개요에서 페이지 번호를 가져올 수 없습니다. 나는 어떻게 든 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에서 제거 된 것으로 보인다. . 내가 java에 대한 (같은 나는이 방법 매개 변수의 목적을 이해하지 못하는 GithubPdfExplicitDestination.getDestinationPage()의 인터넷 구현을 살펴했다 내가 null을 전달하면이 작업 할 것 같다 : 편집

. ToString()을 사용하여 개요 계층 구조에서 한 수준 만 사용하는 pdfs. 제로 인덱스 페이지 번호를 문자열로 반환한다는 것을 의미합니다 .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

고맙습니다. 그것은 내가 예상했던 것보다 더 복잡했다! –