0

I have a pdf file which contains Index Page that includes section with target page. I could get the section name(Section 1.1, Section 5.2) but i can not get the target page number...

For ex: http://www.mikesdotnetting.com/Article/84/iTextSharp-Links-and-Bookmarks

Here is my code:

string FileName = AppDomain.CurrentDomain.BaseDirectory + "TestPDF.pdf";
PdfReader pdfreader = new PdfReader(FileName);
PdfDictionary PageDictionary = pdfreader.GetPageN(9);
PdfArray Annots = PageDictionary.GetAsArray(PdfName.ANNOTS);       
if ((Annots == null) || (Annots.Length == 0))
    return;

foreach (PdfObject oAnnot in Annots.ArrayList)
{
    PdfDictionary AnnotationDictionary = (PdfDictionary)PdfReader.GetPdfObject(oAnnot);          

    if (AnnotationDictionary.Keys.Contains(PdfName.A))
    {
        PdfDictionary oALink = AnnotationDictionary.GetAsDict(PdfName.A);

        if (oALink.Get(PdfName.S).Equals(PdfName.GOTO))
        {
            if (oALink.Keys.Contains(PdfName.D))
            {
                PdfObject objs = oALink.Get(PdfName.D);
                if (objs.IsString())
                {
                    string SectionName = objs.ToString(); // here i could see the section name...
                }
            }
        }
    }
}

How do i get the target page number?

also I couldn't access the Section name for some pdf ex: http://wwwimages.adobe.com/www.adobe.com/content/dam/Adobe/en/devnet/pdf/pdfs/adobe_supplement_iso32000.pdf

In this PDF 9th page contains a section I could not get the section. so please give me solution....

Chris Haas
  • 53,986
  • 12
  • 141
  • 274
Sankar M
  • 4,549
  • 12
  • 37
  • 55
  • Check out my post here, http://stackoverflow.com/a/6599734/231316. Basically do a `oALink.GetAsArray(PdfName.D)` and then call PdfReader.GetPdfObject() on the first item in the ArrayList returned. The object returned should be a reference to a page. I couldn't figure out a way to find the page's "number" so I then loop through each page and compare to my reference. – Chris Haas Apr 25 '12 at 13:00
  • oALink.GetAsArray(PdfName.D) returning NULL value only. but it is working with other pdf except the pdf which i posted ... wy? – Sankar M Apr 25 '12 at 14:09

1 Answers1

3

There's two possible types of Link Annotations, either A or Dest. The A is the more powerful type but is often overkill. The Dest type just specifies an indirect reference to a page along with some fitting and zooming options.

The Dest value can be a couple of different things but is usually (as far as I've ever seen) a named string destination. You can look up named destinations in the document's name destination dictionary. So before your main loop add this so that it can be referenced later:

//Get all existing named destinations
Dictionary<string, PdfObject> dests = pdfreader.GetNamedDestinationFromStrings();

Once you've got the Dest as a string you can look that object up as a key in the above dictionary.

PdfArray thisDest = (PdfArray)dests[AnnotationDictionary.GetAsString(PdfName.DEST).ToString()];

The first item in the array returned is the indirect reference that you're used to. (Actually, the first item could be an integer representing a page number in a remote document so you might have to check for that.)

PdfIndirectReference a = (PdfIndirectReference)thisDest[0];
PdfObject thisPage = PdfReader.GetPdfObject(a);

Below is code that puts most of the above together, omitting some of the code that you already have. A and Dest are mutually exclusive per the spec so no annotation should ever have both specified.

//Get all existing named desitnations
Dictionary<string, PdfObject> dests = pdfreader.GetNamedDestinationFromStrings();

foreach (PdfObject oAnnot in Annots.ArrayList) {
    PdfDictionary AnnotationDictionary = (PdfDictionary)PdfReader.GetPdfObject(oAnnot);

    if (AnnotationDictionary.Get(PdfName.SUBTYPE).Equals(PdfName.LINK)) {
        if (AnnotationDictionary.Contains(PdfName.A)) {
            //...Do normal A stuff here
        } else if (AnnotationDictionary.Contains(PdfName.DEST)) {
            if (AnnotationDictionary.Get(PdfName.DEST).IsString()) {//Named-based destination
                if (dests.ContainsKey(AnnotationDictionary.GetAsString(PdfName.DEST).ToString())) {//See if it exists in the global name dictionary
                    PdfArray thisDest = (PdfArray)dests[AnnotationDictionary.GetAsString(PdfName.DEST).ToString()];//Get the destination
                    PdfIndirectReference a = (PdfIndirectReference)thisDest[0];//TODO, this could actually be an integer for the case of Remote Destinations
                    PdfObject thisPage = PdfReader.GetPdfObject(a);//Get the actual PDF object
                }
            } else if(AnnotationDictionary.Get(PdfName.DEST).IsArray()) {
                //Technically possible, I think the array matches the code directly above but I don't have a sample PDF
            }
        }
    }
}
Leniel Maccaferri
  • 100,159
  • 46
  • 371
  • 480
Chris Haas
  • 53,986
  • 12
  • 141
  • 274