How to Add Tables to PDF Files with Java

Learn how Java applications can call the pdfRest Add to PDF API to generate tables with custom layouts, styles, and data.
Share this page

Why Add Tables to PDF with Java?

The pdfRest Add to PDF API Tool allows developers to programmatically add tables to existing PDF documents. This tutorial will guide you through the process of sending an API call to the Add to PDF endpoint using Java. By utilizing this API, you can enhance your PDF documents dynamically, adding structured data in the form of tables, which can be crucial for reports, invoices, or any document requiring tabular data presentation.

A project manager might need to update a project status report with the latest milestones, owners, and status updates. Instead of manually editing the PDF, the manager can use the Add to PDF API to automate the process, ensuring that the report is always up-to-date and distributed efficiently to stakeholders.

Add Tables to PDF with Java Code Example

import io.github.cdimascio.dotenv.Dotenv;
import java.io.File;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import org.json.JSONArray;
import org.json.JSONObject;

public class PDFWithAddedTables {

  // By default, we use the US-based API service. This is the primary endpoint for global use.
  private static final String API_URL = "https://api.pdfrest.com";

  // For GDPR compliance and enhanced performance for European users, you can switch to the EU-based
  // service by commenting out the URL above and uncommenting the URL below.
  // For more information visit https://pdfrest.com/pricing#how-do-eu-gdpr-api-calls-work
  // private static final String API_URL = "https://eu-api.pdfrest.com";

  private static final String DEFAULT_FILE_PATH = "/path/to/input.pdf";
  private static final String DEFAULT_API_KEY = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";

  // This tagged table uses fixed widths that add up to the table width: 210 + 144 + 150 = 504.
  private static final String TABLE_OBJECTS =
      """
      [
        {
          "page": 1,
          "x": 54,
          "y": 540,
          "width": 504,
          "columns": [{"width": 210}, {"width": 144}, {"width": 150}],
          "tag_structure_type": "Table",
          "style": {
            "padding": {"top": 6, "right": 8, "bottom": 6, "left": 8},
            "text_size": 10
          },
          "header_rows": [
            {
              "cells": [
                {"text": "Milestone", "tag_structure_type": "TH", "style": {"background_color_rgb": [26, 72, 112], "text_color_rgb": [255, 255, 255]}},
                {"text": "Owner", "tag_structure_type": "TH", "style": {"background_color_rgb": [26, 72, 112], "text_color_rgb": [255, 255, 255]}},
                {"text": "Status", "tag_structure_type": "TH", "style": {"background_color_rgb": [26, 72, 112], "text_color_rgb": [255, 255, 255]}}
              ]
            }
          ],
          "rows": [
            {"cells": [{"text": "Requirements review"}, {"text": "Maya Chen"}, {"text": "Complete", "tag_structure_type": "TD", "style": {"background_color_rgb": [220, 252, 231]}}]},
            {"cells": [{"text": "Prototype delivery"}, {"text": "Jordan Lee"}, {"text": "In progress", "tag_structure_type": "TD", "style": {"background_color_rgb": [254, 249, 195]}}]},
            {"cells": [{"text": "Stakeholder approval"}, {"text": "Avery Patel"}, {"text": "Planned", "tag_structure_type": "TD", "style": {"background_color_rgb": [239, 246, 255]}}]}
          ],
          "footer_rows": [
            {
              "cells": [
                {"text": "Next review: Friday, 10:00 AM", "col_span": 3, "tag_structure_type": "TD", "style": {"background_color_rgb": [245, 247, 250], "text_color_rgb": [55, 65, 81]}}
              ]
            }
          ]
        }
      ]
      """;

  public static void main(String[] args) {
    File inputFile = new File(args.length > 0 ? args[0] : DEFAULT_FILE_PATH);
    Dotenv dotenv = Dotenv.configure().ignoreIfMalformed().ignoreIfMissing().load();

    RequestBody fileBody = RequestBody.create(inputFile, MediaType.parse("application/pdf"));
    RequestBody requestBody =
        new MultipartBody.Builder()
            .setType(MultipartBody.FORM)
            .addFormDataPart("file", inputFile.getName(), fileBody)
            .addFormDataPart("table_objects", new JSONArray(TABLE_OBJECTS).toString())
            .addFormDataPart("tag_enabled", "true")
            .addFormDataPart("tag_language", "en-US")
            .addFormDataPart("output", "project-status")
            .build();
    Request request =
        new Request.Builder()
            .header("Accept", "application/json")
            .header("Api-Key", dotenv.get("PDFREST_API_KEY", DEFAULT_API_KEY))
            .url(API_URL + "/pdf-with-added-tables")
            .post(requestBody)
            .build();

    OkHttpClient client = new OkHttpClient.Builder().readTimeout(60, TimeUnit.SECONDS).build();
    try (Response response = client.newCall(request).execute()) {
      System.out.println("Response status code: " + response.code());
      if (response.body() != null) {
        System.out.println(new JSONObject(response.body().string()).toString(2));
      }
    } catch (IOException error) {
      throw new RuntimeException(error);
    }
  }
}

Source: GitHub Repository

Breaking Down the Code

The code begins by importing necessary libraries for handling environment variables, file I/O, HTTP requests, and JSON manipulation. The Dotenv library is used to manage API keys securely.

private static final String API_URL = "https://api.pdfrest.com";

This line sets the base URL for the API. The default is the US-based service, but there's an option to switch to an EU-based service for GDPR compliance.

private static final String DEFAULT_FILE_PATH = "/path/to/input.pdf";
private static final String DEFAULT_API_KEY = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";

These lines define default values for the input PDF file path and the API key. The API key is crucial for authenticating requests to the pdfRest service.

private static final String TABLE_OBJECTS = ...

This JSON string defines the table structure to be added to the PDF. It specifies the page, position, dimensions, and styling of the table, as well as the content of the header, body, and footer rows.

RequestBody requestBody = new MultipartBody.Builder()

This block creates a multipart request body, including the PDF file and table data. It sets the form type and adds form data parts for the file, table objects, tagging options, and output file name.

Request request = new Request.Builder()

This snippet constructs the HTTP request, setting headers for content type and API key, and specifies the endpoint URL for adding tables to the PDF.

OkHttpClient client = new OkHttpClient.Builder().readTimeout(60, TimeUnit.SECONDS).build();

An OkHttpClient instance is created with a 60-second read timeout, which handles the HTTP request execution.

Beyond the Tutorial

In this tutorial, you learned how to use Java to send an API request to pdfRest's Add to PDF endpoint, effectively adding tables to a PDF document. This process can be automated to enhance productivity and ensure accuracy in document updates.

To explore more functionalities, try out all the pdfRest API Tools in the API Lab. For detailed documentation, visit the API Reference Guide.

Note: This example demonstrates a multipart API call. For examples using JSON payloads, visit the GitHub Repository.

Generate a self-service API Key now!
Create your FREE API Key to start processing PDFs in seconds, only possible with pdfRest.