Blog Post

How to Generate PDF Reports from HTML in Java

Illustration: How to Generate PDF Reports from HTML in Java

In this post, you’ll learn how to generate PDF reports from HTML using our Java PDF Generator API. With our API, you receive 100 credits with the free plan. Different operations on a document consume different amounts of credits, so the number of PDF reports you can generate may vary. To access your API key, simply sign up for a free account.

This will be especially useful if you generate and distribute a high volume of standardized reports throughout the year. With our API, you can automate your report generation by dynamically injecting data and content into a standardized HTML template.

We’ll demonstrate how you can generate a report with a free PDF report template in HTML and CSS that can be customized to meet your specific requirements. You can easily style your report by updating the CSS file with your own custom images and fonts. For reports that span multiple pages, you can add a header and footer that repeats across all your pages.

Requirements

To get started, you’ll need:

To access your PSPDFKit API key, sign up for a free account. Your account lets you generate 100 documents for free every month. Once you’ve signed up, you can find your API key in the Dashboard > API Keys section.

This guide uses the latest version of Java Development Kit (JDK) — which is v17.0.1 — and Gradle v7.2.

Information

You can find a similar example made for a receipt template on GitHub.

Creating a New Gradle Project

Create a new Java project for Gradle to build.

Gradle Project

Go to the build.gradle file and add the following dependencies to your project:

dependencies {
    implementation 'com.squareup.okhttp3:okhttp:4.9.2'
    implementation 'org.json:json:20210307'
}

You’ll use the OkHttp library to make HTTP requests to PSPDFKit API, and the org.json library to parse the JSON response.

Downloading the Report Template

Download the report template and extract the contents of the ZIP file into a folder. You’ll get an HTML file, Inter fonts, a Space Mono font, an SVG logo, images, and a README file. Place the files in the root directory of your project.

Preparing the Java Class

  1. Create a new directory in your project. Right-click on your project’s name and select New > Directory.

  2. From there, choose the src/main/java option.

Creating the entry point of your application

  1. Now, right-click on the src/main/java directory and select New > Java Class.

Create a new class called PSPDFKitApiExample that will make HTTP requests to PSPDFKit API.

Creating a Java class screenshot

  1. Add the following code to the PSPDFKitApiExample class:

// src/main/java/PSPDFKitApiExample.java

import java.io.File;
import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;

import org.json.JSONArray;
import org.json.JSONObject;

import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;


public class PspdfkitApiExample {

    public static void main(String[] args) throws IOException {
      // Implement your call to PSPDFKit API here.
    }
}

Set this class as the entry point of your application.

Preparing the Payload

Here, assemble your multipart/form-data body containing the JSON instructions, the HTML file, the stylesheet, the fonts, the images, and the logo file:

final RequestBody body = new MultipartBody.Builder()
   .setType(MultipartBody.FORM)
   .addFormDataPart(
      "index.html",
      "index.html",
      RequestBody.create(
         new File("index.html"),
         MediaType.parse("text/html")
      )
   )
   .addFormDataPart(
      "style.css",
      "style.css",
      RequestBody.create(
         new File("style.css"),
         MediaType.parse("text/css")
      )
   )
   .addFormDataPart(
      "Inter-Regular.ttf",
      "Inter-Regular.ttf",
      RequestBody.create(
         new File("Inter-Regular.ttf"),
         MediaType.parse("font/ttf")
      )
   )
   .addFormDataPart(
      "Inter-Medium.ttf",
      "Inter-Medium.ttf",
      RequestBody.create(
         new File("Inter-Medium.ttf"),
         MediaType.parse("font/ttf")
      )
   )
   .addFormDataPart(
      "Inter-Bold.ttf",
      "Inter-Bold.ttf",
      RequestBody.create(
         new File("Inter-Bold.ttf"),
         MediaType.parse("font/ttf")
      )
   )
   .addFormDataPart(
      "SpaceMono-Regular.ttf",
      "SpaceMono-Regular.ttf",
      RequestBody.create(
         new File("SpaceMono-Regular.ttf"),
         MediaType.parse("font/ttf")
      )
   )
   .addFormDataPart(
      "logo.svg",
      "logo.svg",
      RequestBody.create(
         new File("logo.svg"),
         MediaType.parse("image/svg+xml")
      )
   )
     .addFormDataPart(
      "photo-1.png",
      "photo-1.png",
      RequestBody.create(
         new File("photo-1.png"),
         MediaType.parse("image/png")
      )
   )
     .addFormDataPart(
      "photo-2.png",
      "photo-2.png",
      RequestBody.create(
         new File("photo-2.png"),
         MediaType.parse("image/png")
      )
   )
     .addFormDataPart(
      "photo-3.png",
      "photo-3.png",
      RequestBody.create(
         new File("photo-3.png"),
         MediaType.parse("image/png")
      )
   )
   .addFormDataPart(
      "photo-4.png",
      "photo-4.png",
      RequestBody.create(
         new File("photo-4.png"),
         MediaType.parse("image/png")
      )
   )
   .addFormDataPart(
      "instructions",
      new JSONObject()
         .put("parts", new JSONArray()
         .put(new JSONObject()
         .put("html", "index.html")
         .put("assets", new JSONArray()
            .put("style.css")
            .put("Inter-Regular.ttf")
            .put("Inter-Medium.ttf")
            .put("Inter-Bold.ttf")
            .put("SpaceMono-Regular.ttf")
            .put("logo.svg")
            .put("photo-1.png")
            .put("photo-2.png")
            .put("photo-3.png")
            .put("photo-4.png")
            )
         )
      ).toString()
   )
.build();

Executing the Request

Now, make a request to PSPDFKit API. Make sure to replace the <Your API Key> placeholder with your actual API key:

final Request request = new Request.Builder()
                .url("https://api.pspdfkit.com/build")
                .method("POST", body)
                .addHeader("Authorization", "Bearer <Your API Key>")
                .build();

final OkHttpClient client = new OkHttpClient()
                .newBuilder()
                .build();

final Response response = client.newCall(request).execute();

if (response.isSuccessful()) {
   Files.copy(
      response.body().byteStream(),
      FileSystems.getDefault().getPath("result.pdf"),
      StandardCopyOption.REPLACE_EXISTING
	);
} else {
   // Handle the error.
      throw new IOException(response.body().string());
}

This will send your request to PSPDFKit API and save the response to a file called result.pdf.

To generate the PDF, right-click on the PSPDFKitApiExample file and select Run PSPDFKitApiExample.main().

You can see the full code below:

import java.io.File;
import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;

import org.json.JSONArray;
import org.json.JSONObject;

import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

public final class PspdfkitApiExample {
  public static void main(final String[] args) throws IOException {
    final RequestBody body = new MultipartBody.Builder()
      .setType(MultipartBody.FORM)
      .addFormDataPart(
        "index.html",
        "index.html",
        RequestBody.create(
          new File("index.html"),
          MediaType.parse("text/html")
        )
      )
      .addFormDataPart(
        "style.css",
        "style.css",
        RequestBody.create(
          new File("style.css"),
          MediaType.parse("text/css")
        )
      )
      .addFormDataPart(
        "Inter-Regular.ttf",
        "Inter-Regular.ttf",
        RequestBody.create(
          new File("Inter-Regular.ttf"),
          MediaType.parse("font/ttf")
        )
      )
      .addFormDataPart(
        "Inter-Medium.ttf",
        "Inter-Medium.ttf",
        RequestBody.create(
          new File("Inter-Medium.ttf"),
          MediaType.parse("font/ttf")
        )
      )
      .addFormDataPart(
        "Inter-Bold.ttf",
        "Inter-Bold.ttf",
        RequestBody.create(
          new File("Inter-Bold.ttf"),
          MediaType.parse("font/ttf")
        )
      )
      .addFormDataPart(
        "SpaceMono-Regular.ttf",
        "SpaceMono-Regular.ttf",
        RequestBody.create(
          new File("SpaceMono-Regular.ttf"),
          MediaType.parse("font/ttf")
        )
      )
      .addFormDataPart(
        "logo.svg",
        "logo.svg",
        RequestBody.create(
          new File("logo.svg"),
          MediaType.parse("image/svg+xml")
        )
      )
      .addFormDataPart(
      "photo-1.png",
      "photo-1.png",
      RequestBody.create(
         new File("photo-1.png"),
         MediaType.parse("image/png")
        )
      )
     .addFormDataPart(
      "photo-2.png",
      "photo-2.png",
      RequestBody.create(
         new File("photo-2.png"),
         MediaType.parse("image/png")
        )
      )
     .addFormDataPart(
      "photo-3.png",
      "photo-3.png",
      RequestBody.create(
         new File("photo-3.png"),
         MediaType.parse("image/png")
        )
      )
   .addFormDataPart(
      "photo-4.png",
      "photo-4.png",
      RequestBody.create(
         new File("photo-4.png"),
         MediaType.parse("image/png")
        )
      )
      .addFormDataPart(
        "instructions",
        new JSONObject()
          .put("parts", new JSONArray()
            .put(new JSONObject()
              .put("html", "index.html")
              .put("assets", new JSONArray()
                .put("style.css")
                .put("Inter-Regular.ttf")
                .put("Inter-Medium.ttf")
                .put("Inter-Bold.ttf")
                .put("SpaceMono-Regular.ttf")
                .put("logo.svg")
                .put("photo-1.png")
                .put("photo-2.png")
                .put("photo-3.png")
                .put("photo-4.png")
              )
            )
          ).toString()
      )
      .build();

    final Request request = new Request.Builder()
      .url("https://api.pspdfkit.com/build")
      .method("POST", body)
      .addHeader("Authorization", "Bearer <Your API Key>")
      .build();

    final OkHttpClient client = new OkHttpClient()
      .newBuilder()
      .build();

    final Response response = client.newCall(request).execute();

    if (response.isSuccessful()) {
      Files.copy(
        response.body().byteStream(),
        FileSystems.getDefault().getPath("result.pdf"),
        StandardCopyOption.REPLACE_EXISTING
      );
    } else {
      // Handle the error.
      throw new IOException(response.body().string());
    }
  }
}

Conclusion

In this post, you generated a PDF report from an HTML template using our Java PDF generation API. With the flexibility provided by the credit system, you can tailor your usage based on the specific needs of your reports. We created similar PDF report generation guides using sample code from other programming languages:

In addition to templates for generating reports, we created free templates for other commonly used documents, like receipts, invoices, and certificates. If you’re interested in generating other types of documents in Java, check out the following posts:

All our templates are available for you to download on our PDF Generator API page. Feel free to customize or add any CSS to the template to fit your use case or help reflect your company’s brand.

Author
Hulya Masharipov Technical Writer

Hulya is a frontend web developer and technical writer at Nutrient who enjoys creating responsive, scalable, and maintainable web experiences. She’s passionate about open source, web accessibility, cybersecurity privacy, and blockchain.

Related products
Share post
Free trial Ready to get started?
Free trial