How To Create and Edit PDF Annotations in Java
In this article you'll learn how to leverage four APIs that can be used to programmatically create, retrieve, and/or remove annotations in a PDF document.
Join the DZone community and get the full member experience.
Join For FreePDF file structure – unlike many other common document formats – provides natural, built-in protection for our intellectual property, ensuring unsolicited third parties can’t easily change or delete our content.
Despite this built-in file security, however, PDF files still do provide a meaningful way for document creators and viewers to interact and share ideas. The PDF annotations feature allows (authorized) viewers to provide feedback on a document’s contents by inserting new text (or other) objects at specific points calling out elements of the document’s original content.
PDF annotations are, in effect, superficial objects within a PDF document’s file structure, stored separately from other multimedia objects. They belong to an array called Annots
, which is nested within each PDF’s Page
object – the component of a PDF’s file structure that holds high-level information about each page’s size, rotation, and contents. The location of an annotation on any given PDF page is represented as a set of coordinates, and each individual annotation is assigned its own (zero-based) index value, making it easy to find and retrieve that annotation from within the PDF file encoding.
While there are quite a few methods we can use to automate PDF annotation (or any PDF object editing for that matter), perhaps the simplest and cheapest method involves taking advantage of secure web APIs which are designed specifically to interact with the Annots
array on our behalf. In the remainder of this article, I’ll demonstrate a few free-to-use PDF Annotation APIs which can be called with ready-to-run Java code examples and used to create your own automated PDF annotation workflow.
Demonstration
In this section, I will demonstrate four API solutions that perform basic PDF annotation services. These services include the following:
- Add one or more PDF annotations or comments into a PDF document.
- Get PDF annotations, including comments, from a PDF document.
- Remove a specific annotation or comment from a PDF Document.
- Remove ALL annotations, including comments, from a PDF document.
These services collectively offer developers the ability to create simple automated workflows for creating, retrieving, and removing PDF annotations from a document. Authorization to request resources from each iteration is accomplished through a single free-tier API key (which can be retrieved by registering a free account on the Cloudmersive website).
Below, I’ll first outline simple steps to install the client SDK, and further down the page, I’ll provide example code to help you structure API calls to each service iteration.
To begin SDK installation, let’s first add a reference to the repository in your Maven POM file (Jitpack is used to dynamically compile the library):
<repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>
After that, let’s add a reference to the dependency:
<dependencies>
<dependency>
<groupId>com.github.Cloudmersive</groupId>
<artifactId>Cloudmersive.APIClient.Java</artifactId>
<version>v4.25</version>
</dependency>
</dependencies>
Add One or More PDF Annotations or Comments Into a PDF Document
This API iteration allows us to include new annotations in an existing PDF document by:
- Specifying the input file’s bytes
- Customizing request parameters which collectively create a new PDF annotation object
We can refer to the JSON example value below to review how each request is structured:
{
"InputFileBytes": "string",
"AnnotationsToAdd": [
{
"Title": "string",
"AnnotationType": "string",
"PageNumber": 0,
"AnnotationIndex": 0,
"Subject": "string",
"TextContents": "string",
"CreationDate": "2023-04-07T16:53:55.893Z",
"ModifiedDate": "2023-04-07T16:53:55.893Z",
"LeftX": 0,
"TopY": 0,
"Width": 0,
"Height": 0
}
]
}
As we can see from the above example, the details of each new annotation can be specified outright by including text contents, creation/modification dates, and structural details (coordinates and size values) in the request body.
To structure an API call to this iteration, we can use the following code examples:
// Import classes:
//import com.cloudmersive.client.invoker.ApiClient;
//import com.cloudmersive.client.invoker.ApiException;
//import com.cloudmersive.client.invoker.Configuration;
//import com.cloudmersive.client.invoker.auth.*;
//import com.cloudmersive.client.EditPdfApi;
ApiClient defaultClient = Configuration.getDefaultApiClient();
// Configure API key authorization: Apikey
ApiKeyAuth Apikey = (ApiKeyAuth) defaultClient.getAuthentication("Apikey");
Apikey.setApiKey("YOUR API KEY");
// Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null)
//Apikey.setApiKeyPrefix("Token");
EditPdfApi apiInstance = new EditPdfApi();
AddPdfAnnotationRequest request = new AddPdfAnnotationRequest(); // AddPdfAnnotationRequest |
try {
byte[] result = apiInstance.editPdfAddAnnotations(request);
System.out.println(result);
} catch (ApiException e) {
System.err.println("Exception when calling EditPdfApi#editPdfAddAnnotations");
e.printStackTrace();
}
The underlying service will return the encoding for our newly modified PDF file.
Get PDF Annotations, Including Comments, From a PDF Document
This API iteration retrieves key information about existing annotations and comments within a PDF document, requiring only the input file in its request. We can use this output information to easily modify or remove annotations downstream in our workflow.
We can structure our API call like so:
// Import classes:
//import com.cloudmersive.client.invoker.ApiClient;
//import com.cloudmersive.client.invoker.ApiException;
//import com.cloudmersive.client.invoker.Configuration;
//import com.cloudmersive.client.invoker.auth.*;
//import com.cloudmersive.client.EditPdfApi;
ApiClient defaultClient = Configuration.getDefaultApiClient();
// Configure API key authorization: Apikey
ApiKeyAuth Apikey = (ApiKeyAuth) defaultClient.getAuthentication("Apikey");
Apikey.setApiKey("YOUR API KEY");
// Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null)
//Apikey.setApiKeyPrefix("Token");
EditPdfApi apiInstance = new EditPdfApi();
File inputFile = new File("/path/to/inputfile"); // File | Input file to perform the operation on.
try {
GetPdfAnnotationsResult result = apiInstance.editPdfGetAnnotations(inputFile);
System.out.println(result);
} catch (ApiException e) {
System.err.println("Exception when calling EditPdfApi#editPdfGetAnnotations");
e.printStackTrace();
}
The information returned by this service is structured identically to the request parameters we used in the “Add one or more PDF annotations” iteration above.
Remove a Specific Annotation or Comment From a PDF Document
Using the annotation index we retrieved via the “Get PDF Annotations” API iteration, we can now easily select the annotation we want to remove from our input document and delete it without impacting any other annotations or comments in the process. This iteration’s request parameters include only the input file and the annotation index (which is zero-based).
We can structure our API call using the following code examples:
// Import classes:
//import com.cloudmersive.client.invoker.ApiClient;
//import com.cloudmersive.client.invoker.ApiException;
//import com.cloudmersive.client.invoker.Configuration;
//import com.cloudmersive.client.invoker.auth.*;
//import com.cloudmersive.client.EditPdfApi;
ApiClient defaultClient = Configuration.getDefaultApiClient();
// Configure API key authorization: Apikey
ApiKeyAuth Apikey = (ApiKeyAuth) defaultClient.getAuthentication("Apikey");
Apikey.setApiKey("YOUR API KEY");
// Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null)
//Apikey.setApiKeyPrefix("Token");
EditPdfApi apiInstance = new EditPdfApi();
File inputFile = new File("/path/to/inputfile"); // File | Input file to perform the operation on.
Integer annotationIndex = 56; // Integer | The 0-based index of the annotation in the document
try {
byte[] result = apiInstance.editPdfRemoveAnnotationItem(inputFile, annotationIndex);
System.out.println(result);
} catch (ApiException e) {
System.err.println("Exception when calling EditPdfApi#editPdfRemoveAnnotationItem");
e.printStackTrace();
}
Each request will return the modified PDF encoding with our specified annotations or comments removed.
Remove All Annotations, Including Comments, From a PDF Document
If we’re interested in categorically removing all annotations and comments from a PDF document, we can skip the “Get PDF Annotations” iteration and employ this iteration instead. As the title suggests, this iteration will simply delete all annotations and comments from an input PDF file.
We can use the following code to structure this API call:
// Import classes:
//import com.cloudmersive.client.invoker.ApiClient;
//import com.cloudmersive.client.invoker.ApiException;
//import com.cloudmersive.client.invoker.Configuration;
//import com.cloudmersive.client.invoker.auth.*;
//import com.cloudmersive.client.EditPdfApi;
ApiClient defaultClient = Configuration.getDefaultApiClient();
// Configure API key authorization: Apikey
ApiKeyAuth Apikey = (ApiKeyAuth) defaultClient.getAuthentication("Apikey");
Apikey.setApiKey("YOUR API KEY");
// Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null)
//Apikey.setApiKeyPrefix("Token");
EditPdfApi apiInstance = new EditPdfApi();
File inputFile = new File("/path/to/inputfile"); // File | Input file to perform the operation on.
try {
byte[] result = apiInstance.editPdfRemoveAllAnnotations(inputFile);
System.out.println(result);
} catch (ApiException e) {
System.err.println("Exception when calling EditPdfApi#editPdfRemoveAllAnnotations");
e.printStackTrace();
}
That’s all there is to it. Please note that when formatting new annotations, it’s important to identify the location of each existing object within a PDF document to ensure your annotations are placed accurately on the page.
Opinions expressed by DZone contributors are their own.
Comments