Named destinations
Examples in answer to questions such as:
renamedestinations
JAVA
JAVA
/*
This file is part of the iText (R) project.
Copyright (c) 1998-2023 Apryse Group NV
Authors: Apryse Software.
For more information, please contact iText Software at this address:
sales@itextpdf.com
*/
package com.itextpdf.samples.sandbox.annotations;
import com.itextpdf.kernel.pdf.PdfArray;
import com.itextpdf.kernel.pdf.PdfDictionary;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfName;
import com.itextpdf.kernel.pdf.PdfNameTree;
import com.itextpdf.kernel.pdf.PdfObject;
import com.itextpdf.kernel.pdf.PdfReader;
import com.itextpdf.kernel.pdf.PdfString;
import com.itextpdf.kernel.pdf.PdfWriter;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
public class RenameDestinations {
public static final String DEST = "./target/sandbox/annotations/rename_destinations.pdf";
public static final String SRC = "./src/main/resources/pdfs/nameddestinations.pdf";
public static void main(String[] args) throws Exception {
File file = new File(DEST);
file.getParentFile().mkdirs();
new RenameDestinations().manipulatePdf(DEST);
}
protected void manipulatePdf(String dest) throws Exception {
PdfDocument pdfDoc = new PdfDocument(new PdfReader(SRC), new PdfWriter(dest));
Map<String, PdfString> renamed = new HashMap<>();
PdfNameTree nameTree = pdfDoc.getCatalog().getNameTree(PdfName.Dests);
Map<PdfString, PdfObject> names = nameTree.getNames();
// Loop over all named destinations and rename its string values with new names
for (PdfString key : nameTree.getKeys()) {
String oldName = key.toUnicodeString();
PdfString newName = new PdfString("new" + oldName);
names.put(newName, names.get(key));
names.remove(key);
renamed.put(oldName, newName);
}
// Specify that the name tree has been modified.
// This implies that the name tree will be rewritten on close() method.
nameTree.setModified();
PdfDictionary page = pdfDoc.getPage(1).getPdfObject();
PdfArray annotations = page.getAsArray(PdfName.Annots);
// Loop over all link annotations of the first page and change their destinations.
for (int i = 0; i < annotations.size(); i++) {
PdfDictionary annotation = annotations.getAsDictionary(i);
PdfDictionary action = annotation.getAsDictionary(PdfName.A);
if (action == null) {
continue;
}
PdfString n = action.getAsString(PdfName.D);
if (n != null && renamed.containsKey(n.toString())) {
action.put(PdfName.D, renamed.get(n.toString()));
}
}
pdfDoc.close();
}
}
C#
C#
using System;
using System.Collections.Generic;
using System.IO;
using iText.Kernel.Pdf;
namespace iText.Samples.Sandbox.Annotations
{
public class RenameDestinations
{
public static readonly String DEST = "results/sandbox/annotations/rename_destinations.pdf";
public static readonly String SRC = "../../../resources/pdfs/nameddestinations.pdf";
public static void Main(String[] args)
{
FileInfo file = new FileInfo(DEST);
file.Directory.Create();
new RenameDestinations().ManipulatePdf(DEST);
}
protected void ManipulatePdf(String dest)
{
PdfDocument pdfDoc = new PdfDocument(new PdfReader(SRC), new PdfWriter(dest));
Dictionary<String, PdfString> renamed = new Dictionary<String, PdfString>();
PdfNameTree nameTree = pdfDoc.GetCatalog().GetNameTree(PdfName.Dests);
IDictionary<PdfString, PdfObject> names = nameTree.GetNames();
// Loop over all named destinations and rename its string values with new names
foreach (PdfString key in nameTree.GetKeys())
{
String oldName = key.ToUnicodeString();
PdfString newName = new PdfString("new" + oldName);
names.Add(newName, names[key]);
names.Remove(key);
renamed.Add(oldName, newName);
}
// Specify that the name tree has been modified
// This implies that the name tree will be rewritten on close() method.
nameTree.SetModified();
PdfDictionary page = pdfDoc.GetPage(1).GetPdfObject();
PdfArray annotations = page.GetAsArray(PdfName.Annots);
// Loop over all link annotations of the first page and change their destinations.
for (int i = 0; i < annotations.Size(); i++)
{
PdfDictionary annotation = annotations.GetAsDictionary(i);
PdfDictionary action = annotation.GetAsDictionary(PdfName.A);
if (action == null)
{
continue;
}
PdfString n = action.GetAsString(PdfName.D);
if (n != null && renamed.ContainsKey(n.ToString()))
{
action.Put(PdfName.D, renamed[n.ToString()]);
}
}
pdfDoc.Close();
}
}
}
addnameddestinations
JAVA
JAVA
/*
This file is part of the iText (R) project.
Copyright (c) 1998-2023 Apryse Group NV
Authors: Apryse Software.
For more information, please contact iText Software at this address:
sales@itextpdf.com
*/
package com.itextpdf.samples.sandbox.stamper;
import com.itextpdf.kernel.geom.Rectangle;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfName;
import com.itextpdf.kernel.pdf.PdfObject;
import com.itextpdf.kernel.pdf.PdfPage;
import com.itextpdf.kernel.pdf.PdfReader;
import com.itextpdf.kernel.pdf.PdfString;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.kernel.pdf.navigation.PdfExplicitDestination;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
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 org.w3c.dom.Element;
public class AddNamedDestinations {
public static final String PDF
= "./target/sandbox/stamper/add_named_destinations.pdf";
public static final String SRC
= "./src/main/resources/pdfs/primes.pdf";
public static final String DEST
= "./target/xml/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<Integer> getFactors(int n) {
List<Integer> factors = new ArrayList<Integer>();
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<PdfString, PdfObject> names = pdfDoc.getCatalog().getNameTree(PdfName.Dests).getNames();
for (Map.Entry<PdfString, PdfObject> name : names.entrySet()) {
Element el = doc.createElement("Name");
el.setAttribute("Page", name.getValue().toString());
el.setTextContent(name.getKey().toUnicodeString());
root.appendChild(el);
}
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty("encoding", "ISO8859-1");
transformer.transform(new DOMSource(doc), new StreamResult(dest));
pdfDoc.close();
}
protected void manipulatePdf(String dest) throws Exception {
// Creates directory and new pdf file by content of the read pdf
File file = new File(PDF);
file.getParentFile().mkdirs();
PdfDocument pdfDoc = new PdfDocument(new PdfReader(SRC), new PdfWriter(PDF));
for (int i = 1; i < pdfDoc.getNumberOfPages(); ) {
if (getFactors(++i).size() > 1) {
continue;
}
// Adding named destinations for further usage depending on the needs
PdfPage pdfPage = pdfDoc.getPage(i);
Rectangle pageRect = pdfPage.getPageSize();
float getLeft = pageRect.getLeft();
float getTop = pageRect.getTop();
PdfExplicitDestination destObj = PdfExplicitDestination.createXYZ(pdfPage, getLeft, getTop, 1);
pdfDoc.addNamedDestination("prime" + i, destObj.getPdfObject());
}
pdfDoc.close();
createXml(PDF, dest);
}
}
C#
C#
using System;
using System.Collections.Generic;
using System.IO;
using System.Xml;
using iText.Kernel.Geom;
using iText.Kernel.Pdf;
using iText.Kernel.Pdf.Navigation;
namespace iText.Samples.Sandbox.Stamper
{
public class AddNamedDestinations
{
public static readonly String PDF = "results/sandbox/stamper/add_named_destinations.pdf";
public static readonly String SRC = "../../../resources/pdfs/primes.pdf";
public static readonly String DEST = "results/xml/primes_with_destination.xml";
public static void Main(String[] args)
{
FileInfo file = new FileInfo(DEST);
file.Directory.Create();
new AddNamedDestinations().ManipulatePdf(DEST);
}
public static IList<int> GetFactors(int n)
{
IList<int> factors = new List<int>();
for (int i = 2; i <= n; i++) {
while (n % i == 0) {
factors.Add(i);
n /= i;
}
}
return factors;
}
/// <summary>Create an XML file with named destinations</summary>
/// <param name="src">The path to the PDF with the destinations</param>
/// <param name="dest">The path to the XML file</param>
public void CreateXml(String src, String dest)
{
PdfDocument pdfDoc = new PdfDocument(new PdfReader(src));
XmlDocument doc = new XmlDocument();
XmlElement root = doc.CreateElement("Destination");
doc.AppendChild(root);
IDictionary<PdfString, PdfObject> names = pdfDoc.GetCatalog().GetNameTree(PdfName.Dests).GetNames();
foreach (KeyValuePair<PdfString, PdfObject> name in names)
{
XmlElement el = doc.CreateElement("Name");
el.SetAttribute("Page", name.Value.ToString());
el.InnerText = name.Key.ToUnicodeString();
root.AppendChild(el);
}
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;
XmlWriter writer = XmlWriter.Create(dest, settings);
root.WriteTo(writer);
writer.Close();
pdfDoc.Close();
}
protected void ManipulatePdf(String dest)
{
// Creates directory and new pdf file by content of the read pdf
FileInfo file = new FileInfo(PDF);
file.Directory.Create();
PdfDocument pdfDoc = new PdfDocument(new PdfReader(SRC), new PdfWriter(PDF));
for (int i = 1; i < pdfDoc.GetNumberOfPages(); )
{
if (GetFactors(++i).Count > 1)
{
continue;
}
// Adding named destinations for further usage depending on the needs
PdfPage pdfPage = pdfDoc.GetPage(i);
Rectangle pageRect = pdfPage.GetPageSize();
float getLeft = pageRect.GetLeft();
float getTop = pageRect.GetTop();
PdfExplicitDestination destObj = PdfExplicitDestination.CreateXYZ(pdfPage, getLeft, getTop, 1);
pdfDoc.AddNamedDestination("prime" + i, destObj.GetPdfObject());
}
pdfDoc.Close();
CreateXml(PDF, dest);
}
}
}