Adding Bookmarks to a PDF
Use the Outline element in JSON instructions with the pdf
endpoint to create a PDF that includes bookmarks for a combined PDF.
In this tutorial you merge three PDF documents and combine the three PDFs and add bookmarks to the merged PDF document. You also create a bookmark with an external URL and add it to the PDF's outline.
#
Required ResourcesTo complete this tutorial, add the Adding Bookmarks sample to your samples
folder in your cloud storage space using the Resource Manager. After adding the sample resources, you should see the samples/adding-bookmarks-pdf-endpoint
folder containing the resources used in this tutorial.
Sample | Sample Folder | Resources |
---|---|---|
Adding Bookmarks | samples/adding-bookmarks-pdf-endpoint | DocumentA.pdf , DocumentB.pdf , DocumentC.pdf , and instructions.json |
From the Resource Manager, download the three PDF documents and
instructions.json
to your local system; here we assume/temp/dynamicpdf-api-samples/add-bookmarks
.After downloading, delete the three PDFs and
instructions.json
from your cloud storage space using the Resource Manager. We delete these resources so that we can use the resources from the previous tutorial.
info
If you do not plan on duplicating this tutorial's steps, then do not delete the resources.
Resource | Cloud/Local |
---|---|
DocumentA.pdf | local |
DocumentB.pdf | local |
DocumentC.pdf | local |
instructions.json | local |
tip
See Sample Resources for instructions on adding sample resources.
#
Obtaining API KeyThis tutorial assumes a valid API key obtained from the DynamicPDF Cloud API's Environment Manager
. Refer to the following for instructions on getting an API key.
tip
If you are not familiar with the Resource Manager or Apps and API Keys, refer to the following tutorial and relevant Users Guide pages.*
#
Calling API Directly Using POSTMerging three pre-existing PDFs and saving them as a new PDF requires using the pdf
endpoint. The pdf
endpoint uses an instructions JSON document you send to the endpoint. The endpoint then processes the instructions to create the resultant PDF. When you call the pdf
endpoint directly, you must create an instructions document. When you use one of the DynamicPDF client libraries, the client library hides the complexities of creating the instructions document from you.
Now let's create the JSON instructions document.
#
Create JSON Instructions- Open a text editor and create the following instructions JSON document and name it
instructions.json
. - Add the three inputs of type
pdf
. - Assign each input an
id
. - Add the bookmarks to the instructions.
- Note that each outline element refers to the
id
of its related document. - Save
instructions.json
to/temp/dynamicpdf-api-samples/add-bookmarks
.
{ "inputs": [ { "type": "pdf", "resourceName": "DocumentA.pdf", "id": "documentA" }, { "type": "pdf", "resourceName": "DocumentB.pdf", "id": "documentB" }, { "type": "pdf", "resourceName": "DocumentC.pdf", "id": "documentC" } ], "outlines": [ { "color": "Red", "text": "Three Bookmarks", "style": "boldItalic", "expanded": true, "children": [ { "color": "Orange", "text": "DocumentA", "linkTo": { "inputID": "documentA" } }, { "color": "Green", "text": "DocumentB", "linkTo": { "inputID": "documentB", "pageOffset": 2 } }, { "color": "Purple", "text": "DocumentC", "linkTo": { "inputID": "documentC" } }, { "color": "Blue", "text": "DynamicPDF Cloud API", "linkTo": { "url": "https://cloud.dynamicpdf.com/" } } ] } ]}
The inputs
array refers to the inputs to the created PDF. The outlines array lists any outlines added to the PDF. Note that each input has an id
corresponding to the inputID
value in the outline element. The inputID
ties the outline to the resource. Finally, the fourth outline element is a link to an external URL.
We can now use the cURL
command to call the pdf
endpoint.
#
cURL CommandBefore calling the cURL
command, ensure you have the following resources in your local filesystem.
/temp/dynamicpdf-api-samples/add-bookmarks |
---|
instructions.json |
DocumentA.pdf |
DocumentB.pdf |
DocumentC.pdf |
- Create the following cURL command and call the
pdf
endpoint.
curl https://api.dynamicpdf.com/v1.0/pdf -H "Authorization:Bearer DP.xxx--api-key--xxx" -F "Instructions=@C:/temp/dynamicpdf-api-samples/add-bookmarks/instructions.json" -F "Resource=@C:/temp/dynamicpdf-api-samples/add-bookmarks/DocumentA.pdf" -F "Resource=@C:/temp/dynamicpdf-api-samples/add-bookmarks/DocumentB.pdf" -F "Resource=@C:/temp/dynamicpdf-api-samples/add-bookmarks/DocumentC.pdf" -o add-bookmarks-output.pdf
In the preceding cURL command, the -H
parameter specifies that a header variable named Authorization
is sent to the endpoint. The first -F
parameter specifies that it is a form field with the name of Instructions
and the path to the instructions document as the value. The second, third, and fourth -F
parameters specify Resource
as the form field and then the path to the local file as the value.
tip
If a filename in the cURL command does not match the filename in the instructions document, then add the filename by using a semicolon followed by the filename from the instructions document.
"Resource=@C:/temp/dynamicpdf-api-samples/DocumentB.pdf;MyDocument"
The -o
parameter specifies the output file to write the response to.
info
Note that we are assuming the cURL
command is executed in the same folder as where we stored our resources. If calling cURL
from somewhere other than the folder containing your resources, then you must also specify the path to the outputted document.
- Execute the curl command and generate the PDF document.
- Open the created PDF,
add-bookmarks-output.pdf
to view the merged PDF with the added bookmarks.
Figure 1. The PDF has three bookmarks and a link to an external website.
#
Calling Endpoint Using Client LibraryOf course, creating an instructions document by hand can be tedious and error-prone. To simplify your development, you can instead use one of the DynamicPDF Cloud API client libraries.
Let's use the client libraries to generate the PDF rather than the instructions document.
#
Complete SourceUse the client library of your choice to complete the next tutorial section. Each client library tab contains tutorial steps particular to the selected language.
Access the complete source for this project at one of the following GitHub projects.
Language | GitHub Users Guide Project | Example Class File | Location/Package/Namespace |
---|---|---|---|
C# | https://github.com/dynamicpdf-api/dotnet-client-examples | Program.cs | namespace AddBookmarks |
Java | https://github.com/dynamicpdf-api/java-client-examples | AddBookmarks.java | com.dynamicpdf.api.examples |
Node.js | https://github.com/dynamicpdf-api/nodejs-client-examples | AddBookmarks.js | nodejs-client-examples |
PHP | https://github.com/dynamicpdf-api/php-client-examples | AddBookmarks.php | php-client-examples |
tip
Click on the language tab of choice to view the tutorial steps for the particular language.
- C# (.NET)
- Java
- Node.js
- PHP
Available on NuGet:
Install-Package DynamicPDF.API
- Create a new Console App (.NET Core) project named
AddBookmarks
. - Add the DynamicPDF.API NuGet package.
- Create a new static method named
Run
. - Add the following code to the
Run
method. - Create a new
Pdf
instance and assign the api key. - Create three new
PdfResource
instances, one for each PDF to be merged. - Add the
PdfResource
to thePdf
instance, but return a reference to eachPdfInput
instance. - Set the
Id
of each input to the document's name. - Create a top level root outline and make the color red.
- Add three child outline elements and set each element's color.
- Create a new URL outline element and assign it a
UrlAction
. - Call the
Pdf
instance'sProcess
method. - If the results is successful, then save the PDF response
Content
(a byte array) to a file.
using DynamicPDF.Api;using System;using System.IO;
namespace AddBookmarks{ class Program { static void Main(string[] args) { Run("DP.xxx--apikey---xxx", "C:/temp/dynamicpdf-api-samples/add-bookmarks/"); }
public static void Run(String apiKey, String basePath) { Pdf pdf = new Pdf(); pdf.ApiKey = apiKey;
//add three PDF documents as PdfInputs
PdfResource resource = new PdfResource(basePath + "DocumentA.pdf"); PdfInput inputA = pdf.AddPdf(resource); inputA.Id = "documentA";
PdfResource resourceB = new PdfResource(basePath + "DocumentB.pdf"); PdfInput inputB = pdf.AddPdf(resourceB); inputB.Id = "documentB";
PdfResource resourceC = new PdfResource(basePath + "DocumentC.pdf"); PdfInput inputC = pdf.AddPdf(resourceC); inputC.Id = "documentC";
//create a root outline and then add the three documents as children Outline instances
Outline rootOutline = pdf.Outlines.Add("Three Bookmarks"); Outline outlineA = rootOutline.Children.Add("DocumentA", inputA); Outline outlineB = rootOutline.Children.Add("DocumentB", inputB, 2); rootOutline.Children.Add("DocumentC", inputC).Color = RgbColor.Purple;
//add some color to the outline elements
rootOutline.Color = RgbColor.Red; rootOutline.Style = OutlineStyle.BoldItalic; outlineA.Color = RgbColor.Orange; outlineB.Color = RgbColor.Green;
//add an outline element that links to a URL
Outline outlineD = rootOutline.Children.Add("DynamicPDF Cloud API"); outlineD.Color = RgbColor.Blue; outlineD.Action = new UrlAction("https://cloud.dynamicpdf.com/");
rootOutline.Expanded = true;
PdfResponse response = pdf.Process(); if(response.IsSuccessful) { Console.WriteLine(PrettyPrintUtil.JsonPrettify(pdf.GetInstructionsJson())); File.WriteAllBytes(basePath + "add-bookmarks-output.pdf", response.Content); } else { Console.WriteLine(PrettyPrintUtil.JsonPrettify(pdf.GetInstructionsJson())); Console.WriteLine(response.ErrorJson); } }
}}
Available on NPM:
npm i @dynamicpdf/api
- Use npm to install the DynamicPDF Cloud API module.
- Create a new class named
AddBookmarks
. - Create a static
Run
method. - Add the following code to the
Run
method. - Create a new
Pdf
instance and assign the api key. - Create three new
PdfResource
instances, one for each PDF to be merged. - Add the
PdfResource
to thePdf
instance, but return a reference to eachPdfInput
instance. - Set the
Id
of each input to the document's name. - Create a top level root outline and make the color red.
- Add three child outline elements and set each element's color.
- Create a new URL outline element and assign it a
UrlAction
. - Call the
Pdf
instance'sprocess
method. - Add the call to execute the
Run
method.
import fs from 'fs';import { Pdf, PdfResource, RgbColor, Outline, UrlAction} from "@dynamicpdf/api"import { Console } from 'console';
export class AddBookmarks {
static async Run() {
var pdf = new Pdf(); pdf.apiKey = "xxxx--apikey----xxxx";
var resourceA = new PdfResource("c:/temp/dynamicpdf-api-samples/add-bookmarks/DocumentA.pdf"); var resourceB = new PdfResource("c:/temp/dynamicpdf-api-samples/add-bookmarks/DocumentB.pdf"); var resourceC = new PdfResource("c:/temp/dynamicpdf-api-samples/add-bookmarks/DocumentC.pdf");
var inputA = pdf.addPdf(resourceA); inputA.Id = "DocumentA";
var inputB = pdf.addPdf(resourceB); inputB.Id = "DocumentB";
var inputC = pdf.addPdf(resourceC); inputC.Id = "DocumentC";
var rootOutline = pdf.outlines.add("Three Bookmarks"); rootOutline.expanded = true;
var childOutlineA = rootOutline.children.add("DocumentA", inputA); var childOutlineB = rootOutline.children.add("DocumentB", inputB, 2); var childOutlineC = rootOutline.children.add("DocumentC", inputC);
childOutlineA.color = RgbColor.red; childOutlineB.color = RgbColor.orange; childOutlineC.color = RgbColor.green;
var outlineD = rootOutline.children.add("DynamicPDF Cloud API"); outlineD.color = RgbColor.blue; outlineD.action = new UrlAction("https://cloud.dynamicpdf.com/");
var res = await pdf.process();
if (res.isSuccessful) { var outFile = "c:/temp/dynamicpdf-api-samples/add-bookmarks/add-bookmarks-output.pdf"; var outStream = fs.createWriteStream(outFile); outStream.write(res.content); } else { console.log(res.errorJson); } }}await AddBookmarks.Run();
- Run the application,
node AddBookmarks.js
, and if the the response is successful, then save the PDF responsecontent
(a byte array) to a file.
Available on Maven:
https://search.maven.org/search?q=g:com.dynamicpdf.api
<dependency> <groupId>com.dynamicpdf.api</groupId> <artifactId>dynamicpdf-api</artifactId> <version>1.0.0</version></dependency>
- Create a new Maven project and add the DynamicPDF API as a dependency, also add the Apache Commons IO library.
<dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.8.0</version></dependency>
- Create a new class named
AddBookmarks
with amain
method. - Create a new method named
Run
. - Add the
Run
method call tomain
. - Create a new
Pdf
instance and assign the api key. - Create three new
PdfResource
instances, one for each PDF to be merged. - Add the
PdfResource
to thePdf
instance, but return a reference to eachPdfInput
instance. - Set the
Id
of each input to the document's name. - Create a top level root outline and make the color red.
- Add three child outline elements and set each element's color.
- Create a new URL outline element and assign it a
UrlAction
. - Call the
Pdf
instance'sProcess
method. - Run the application and if the the response is successful, then save the PDF response
content
(a byte array) to a file.
package com.dynamicpdf.api.examples;
import java.io.File;import java.io.IOException;
import org.apache.commons.io.FileUtils;
import com.dynamicpdf.api.Outline;import com.dynamicpdf.api.OutlineStyle;import com.dynamicpdf.api.Pdf;import com.dynamicpdf.api.PdfInput;import com.dynamicpdf.api.PdfResource;import com.dynamicpdf.api.PdfResponse;import com.dynamicpdf.api.RgbColor;import com.dynamicpdf.api.UrlAction;
public class AddBookmarks {
public static void main(String[] args) { AddBookmarks.Run("DP.xxxx--apikey--xxxx", "C:/temp/dynamicpdf-api-samples/add-bookmarks/"); }
public static void Run(String apiKey, String basePath) { Pdf pdf = new Pdf(); pdf.setApiKey(apiKey);
//add three PDF documents as PdfInputs
PdfResource resource = new PdfResource(basePath + "DocumentA.pdf"); PdfInput inputA = pdf.addPdf(resource); inputA.setId("documentA");
PdfResource resourceB = new PdfResource(basePath + "DocumentB.pdf"); PdfInput inputB = pdf.addPdf(resourceB); inputB.setId("documentB");
PdfResource resourceC = new PdfResource(basePath + "DocumentC.pdf"); PdfInput inputC = pdf.addPdf(resourceC); inputC.setId("documentC");
//create a root outline and then add the three documents as children Outline instances
Outline rootOutline = pdf.getOutlines().add("Three Bookmarks"); Outline outlineA = rootOutline.getChildren().add("DocumentA", inputA); Outline outlineB = rootOutline.getChildren().add("DocumentB", inputB, 2); rootOutline.getChildren().add("DocumentC", inputC).setColor(RgbColor.getPurple());
//add some color to the outline elements
rootOutline.setColor(RgbColor.getRed()); rootOutline.setStyle(OutlineStyle.BOLDITALIC); outlineA.setColor(RgbColor.getOrange()); outlineB.setColor(RgbColor.getGreen());
//add an outline element that links to a URL
Outline outlineD = rootOutline.getChildren().add("DynamicPDF Cloud API"); outlineD.setColor(RgbColor.getBlue()); outlineD.setAction(new UrlAction("https://cloud.dynamicpdf.com/"));
rootOutline.setExpanded(true);
PdfResponse response = pdf.process();
if(response.getIsSuccessful()) { try { FileUtils.writeByteArrayToFile(new File(basePath + "add-bookmarks-output.pdf"), response.getContent()); } catch (IOException e) { e.printStackTrace(); } } else { System.out.println(response.getErrorJson()); } }
}
Available as a Composer package:
composer require dynamicpdf/api
- Use composer to ensure you have the required PHP libraries.
- Create a new class named
CompletingAcroForm
. - Add a
Run
method. - Create a new
Pdf
instance and assign the api key. - Create three new
PdfResource
instances, one for each PDF to be merged. - Add the
PdfResource
to thePdf
instance, but return a reference to eachPdfInput
instance. - Set the
Id
of each input to the document's name. - Create a top level root outline and make the color red.
- Add three child outline elements and set each element's color.
- Create a new URL outline element and assign it a
UrlAction
. - Call the
Pdf
instance'sProcess
method. - Add the call to execute the
Run
method.
<?php
require __DIR__ . '/vendor/autoload.php';
use DynamicPDF\Api\Pdf;use DynamicPDF\Api\PdfResource;use DynamicPDF\Api\PdfInput;use DynamicPDF\Api\RgbColor;use DynamicPDF\Api\UrlAction;
class AddBookmarks{ private static string $BasePath = "C:/temp/dynamicpdf-api-samples/add-bookmarks/";
public static function Run() { $pdf = new Pdf(); $pdf->ApiKey ="DP.xxxx--apikeys--xxxx";
$resourceA = new PdfResource(AddBookmarks::$BasePath . "DocumentA.pdf"); $resourceB = new PdfResource(AddBookmarks::$BasePath . "DocumentB.pdf"); $resourceC = new PdfResource(AddBookmarks::$BasePath . "DocumentC.pdf");
$inputA = $pdf->AddPdf($resourceA); $inputA->Id = "documentA"; $inputB = $pdf->AddPdf($resourceB); $inputB->Id = "documentB"; $inputC = $pdf->AddPdf($resourceC); $inputC->Id = "documentC";
array_push($pdf->Inputs, $inputA); array_push($pdf->Inputs, $inputB); array_push($pdf->Inputs, $inputC); //create a root outline and then add the three documents as children Outline instances
$rootOutline = $pdf->Outlines->Add("Three Bookmarks"); $rootOutline->Expanded = true;
$outlineA = $rootOutline->Children->Add("DocumentA", $inputA); $outlineB = $rootOutline->Children->Add("DocumentB", $inputB, 2); $outlineC = $rootOutline->Children->Add("DocumentC", $inputC);
//add some color to the outline elements
$rootOutline->Color = RgbColor::Red(); $outlineA->Color = RgbColor::Orange(); $outlineB->Color = RgbColor::Green(); $outlineA->Color = RgbColor::Purple(); //add an outline element that links to a URL
$outlineD = $rootOutline->Children->Add("DynamicPDF Cloud API"); $outlineD->Color = RgbColor::Blue(); $outlineD->Action = new UrlAction("https://cloud.dynamicpdf.com");
$response = $pdf->Process();
//if successul write to file if($response->IsSuccessful) { file_put_contents(AddBookmarks::$BasePath . "add-bookmarks-output.pdf", $response->Content); } else { echo($response->ErrorMessage); }
}}AddBookmarks::Run();
- Run the application,
php AddBookmarks.php
, and if the the response is successful, then save the PDF responsecontent
(a byte array) to a file.
In all four examples, the processing steps were the same. First, we created a new Pdf
instance to construct the finished PDF. We then loaded four PDFs into PdfResource
instances and added them to the Pdf
instance. We used the resulting references to PdfInput
to assign IDs for each added PDF.
After adding the PDF documents to merge, we obtained a reference to an Outline
instance from the Pdf
instance by adding a new outline with text. We then added three more Outline
instances as children to the top-level Outline
instance. Then we added a final Outline
instance that linked to a URL.
The endpoint returned a merged PDF where each outline element is a bookmark to the original PDF that was merged.
Figure 2. The outline created by merging three PDFs and a URL to an external website.