Named destinations

This is a code example of iText PDF, discover more.

31st May 2016
admin-marketing

Switch code for this example

RenameDestinations.java
/*

    This file is part of the iText (R) project.
    Copyright (c) 1998-2016 iText Group NV

*/

/**
 * Example written by Bruno Lowagie in answer to:
 * http://stackoverflow.com/questions/20131610/renaming-named-destinations-in-pdf-files
 * 

* Searching for all the named destinations, with the purpose to rename them. * Change the destination for all GoTo actions from Link annotations on the first page. */ package com.itextpdf.samples.sandbox.annotations; import com.itextpdf.kernel.pdf.*; import com.itextpdf.samples.GenericTest; import com.itextpdf.test.annotations.type.SampleTest; import org.junit.experimental.categories.Category; import java.io.File; import java.util.HashMap; import java.util.Map; @Category(SampleTest.class) public class RenameDestinations extends GenericTest { public static final String DEST = "./target/test/resources/sandbox/annotations/rename_destinations.pdf"; public static final String SRC = "./src/test/resources/pdfs/nameddestinations.pdf"; public static void main(String[] args) throws Exception { File file = new File(DEST); file.getParentFile().mkdirs(); new RenameDestinations().manipulatePdf(DEST); } @Override protected void manipulatePdf(String dest) throws Exception { PdfDocument pdfDoc = new PdfDocument(new PdfReader(SRC), new PdfWriter(DEST)); Map renamed = new HashMap<>(); PdfDictionary catalog = pdfDoc.getCatalog().getPdfObject(); PdfDictionary names = catalog.getAsDictionary(PdfName.Names); PdfDictionary dests = names.getAsDictionary(PdfName.Dests); PdfArray name = dests.getAsArray(PdfName.Names); for (int i = 0; i < name.size(); i += 2) { PdfString original = name.getAsString(i); PdfString newName = new PdfString("new" + original.toString()); name.set(i, newName); renamed.put(original.toString(), newName); } PdfDictionary page = pdfDoc.getPage(1).getPdfObject(); PdfArray annotations = page.getAsArray(PdfName.Annots); PdfDictionary annotation; PdfDictionary action; PdfString n; for (int i = 0; i < annotations.size(); i++) { annotation = annotations.getAsDictionary(i); action = annotation.getAsDictionary(PdfName.A); if (action == null) continue; n = action.getAsString(PdfName.D); if (n != null && renamed.containsKey(n.toString())) { action.put(PdfName.D, renamed.get(n.toString())); } } pdfDoc.close(); } }

AddNamedDestinations.java
/*

    This file is part of the iText (R) project.
    Copyright (c) 1998-2016 iText Group NV

*/

/**
 * Example written by Bruno Lowagie in answer to:
 * http://stackoverflow.com/questions/29884833/add-named-destinations-to-an-existing-pdf-document-with-itext
 */
package com.itextpdf.samples.sandbox.stamper;

import com.itextpdf.kernel.pdf.*;
import com.itextpdf.samples.GenericTest;
import com.itextpdf.test.annotations.type.SampleTest;

import org.junit.experimental.categories.Category;
import org.w3c.dom.Element;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Category(SampleTest.class)
public class AddNamedDestinations extends GenericTest {
    public static final String DEST
            = "./target/test/resources/sandbox/stamper/add_named_destinations.pdf";
    public static final String SRC
            = "./src/test/resources/pdfs/primes.pdf";
    public static final String XML
            = "./target/test/resources/sandbox/stamper/primes_with_destination.xml";

    public static void main(String[] args) throws Exception {
        File file = new File(DEST);
        file.getParentFile().mkdirs();
        new AddNamedDestinations().manipulatePdf(DEST);
    }

    public static List getFactors(int n) {
        List factors = new ArrayList();
        for (int i = 2; i <= n; i++) {
            while (n % i == 0) {
                factors.add(i);
                n /= i;
            }
        }
        return factors;
    }

    /**
     * Create an XML file with named destinations
     *
     * @param src  The path to the PDF with the destinations
     * @param dest The path to the XML file
     * @throws java.io.IOException
     */
    public void createXml(String src, String dest) throws IOException,
            ParserConfigurationException, TransformerException {
        PdfDocument pdfDoc = new PdfDocument(new PdfReader(src));

        DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder db = docFactory.newDocumentBuilder();

        org.w3c.dom.Document doc = db.newDocument();
        Element root = doc.createElement("Destination");
        doc.appendChild(root);

        Map names = pdfDoc.getCatalog().getNameTree(PdfName.Dests).getNames();
        for (Map.Entry name : names.entrySet()) {
            Element el = doc.createElement("Name");
            el.setAttribute("Page", name.getValue().toString());
            el.setTextContent(name.getKey());
            root.appendChild(el);
        }

        TransformerFactory tf = TransformerFactory.newInstance();
        Transformer t = tf.newTransformer();
        t.setOutputProperty("encoding", "ISO8859-1");

        t.transform(new DOMSource(doc), new StreamResult(dest));
        pdfDoc.close();
    }

    @Override
    protected void manipulatePdf(String dest) throws Exception {
        PdfDocument pdfDoc = new PdfDocument(new PdfReader(SRC), new PdfWriter(dest));
        int n = pdfDoc.getNumberOfPages();
        for (int i = 1; i < n; ) {
            if (getFactors(++i).size() > 1) {
                continue;
            }
            PdfArray array = new PdfArray();
            array.add(pdfDoc.getPage(i).getPdfObject());
            array.add(PdfName.XYZ);
            array.add(new PdfNumber(pdfDoc.getPage(i).getPageSize().getLeft()));
            array.add(new PdfNumber(pdfDoc.getPage(i).getPageSize().getTop()));
            array.add(new PdfNumber(1));
            // Notice that the document has already destinations like "Prime+i"
            pdfDoc.addNamedDestination("prime" + i, array);
        }
        pdfDoc.close();

        createXml(DEST, XML);
    }
}
Contact

Still have questions? 

We're happy to answer your questions. Reach out to us and we'll get back to you shortly.

Contact us
Stay updated

Join 11,000+ subscribers and become an iText PDF expert by staying up to date with our new products, updates, tips, technical solutions and happenings.

Subscribe Now