Java Integration

Learn how to generate PDFs from your Java application using the modern HttpClient API introduced in Java 11.

Why use PixelToPdf with Java?

Java's enterprise-grade stability makes it ideal for mission-critical document generation. PixelToPdf integrates seamlessly with Spring Boot, Jakarta EE, and standalone applications. Generate invoices, contracts, reports, and certificates with pixel-perfect rendering and zero server-side dependencies.

Prerequisites

  • Java 11+ (for the built-in HttpClient) or any version with Apache HttpClient
  • A PixelToPdf API key from your dashboard (free tier available)

Basic Example

This example uses Java's built-in HttpClient (Java 11+) to convert a webpage to PDF. We use System.getenv() to securely read the API key from environment variables.

PixelToPdfExample.java
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.file.Files;
import java.nio.file.Path;

public class PixelToPdfExample {
    public static void main(String[] args) throws Exception {
        HttpClient client = HttpClient.newHttpClient();

        String json = """
            {"source": "https://example.com"}
            """;

        HttpRequest request = HttpRequest.newBuilder()
            .uri(URI.create("https://api.pixeltopdf.com/convert/pdf"))
            .header("X-API-Key", System.getenv("PIXELTOPDF_API_KEY"))
            .header("Content-Type", "application/json")
            .POST(HttpRequest.BodyPublishers.ofString(json))
            .build();

        HttpResponse<byte[]> response = client.send(
            request,
            HttpResponse.BodyHandlers.ofByteArray()
        );

        if (response.statusCode() == 200) {
            Files.write(Path.of("output.pdf"), response.body());
            System.out.println("PDF saved to output.pdf");
        } else {
            System.err.println("Error: " + response.statusCode());
        }
    }
}

How it works: The HttpClient sends an async-capable HTTP request. We use BodyHandlers.ofByteArray() to receive the PDF as raw bytes, which are then written to disk using Files.write(). The text block syntax (""") makes JSON easy to write inline.

Convert HTML String

For dynamic documents, pass your HTML directly as a string. This example includes a helper function to properly escape HTML content for JSON. Java's text blocks make multi-line strings clean and readable.

HtmlToPdf.java
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.file.Files;
import java.nio.file.Path;

public class HtmlToPdf {
    public static void main(String[] args) throws Exception {
        HttpClient client = HttpClient.newHttpClient();

        String html = """
            <!DOCTYPE html>
            <html>
            <head>
              <style>
                body { font-family: Arial, sans-serif; padding: 40px; }
                h1 { color: #333; }
              </style>
            </head>
            <body>
              <h1>Hello, PixelToPdf!</h1>
              <p>This PDF was generated from HTML.</p>
            </body>
            </html>
            """;

        String json = String.format("""
            {
              "source": %s,
              "format": "A4",
              "margin": {"top": "20mm", "bottom": "20mm", "left": "20mm", "right": "20mm"}
            }
            """, escapeJson(html));

        HttpRequest request = HttpRequest.newBuilder()
            .uri(URI.create("https://api.pixeltopdf.com/convert/pdf"))
            .header("X-API-Key", System.getenv("PIXELTOPDF_API_KEY"))
            .header("Content-Type", "application/json")
            .POST(HttpRequest.BodyPublishers.ofString(json))
            .build();

        HttpResponse<byte[]> response = client.send(
            request,
            HttpResponse.BodyHandlers.ofByteArray()
        );

        Files.write(Path.of("output.pdf"), response.body());
    }

    private static String escapeJson(String str) {
        return "\"" + str.replace("\\", "\\\\")
                         .replace("\"", "\\\"")
                         .replace("\n", "\\n") + "\"";
    }
}

Tip: For production code, consider using a JSON library like Jackson or Gson instead of manual string formatting. The margin option accepts values in mm, cm, in, or px.

With Spring Boot

This Spring controller creates an endpoint that generates PDFs on-demand. When users visit /invoice/123/pdf, they'll download the invoice as a PDF file.

InvoiceController.java
import org.springframework.http.*;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

@RestController
public class InvoiceController {

    private final RestTemplate restTemplate = new RestTemplate();

    @GetMapping("/invoice/{id}/pdf")
    public ResponseEntity<byte[]> downloadInvoice(@PathVariable String id) {
        HttpHeaders headers = new HttpHeaders();
        headers.set("X-API-Key", System.getenv("PIXELTOPDF_API_KEY"));
        headers.setContentType(MediaType.APPLICATION_JSON);

        String json = String.format(
            "{\"source\": \"https://yourapp.com/invoice/%s/html\"}",
            id
        );

        HttpEntity<String> entity = new HttpEntity<>(json, headers);

        ResponseEntity<byte[]> response = restTemplate.exchange(
            "https://api.pixeltopdf.com/convert/pdf",
            HttpMethod.POST,
            entity,
            byte[].class
        );

        return ResponseEntity.ok()
            .header(HttpHeaders.CONTENT_DISPOSITION,
                    "attachment; filename=invoice-" + id + ".pdf")
            .contentType(MediaType.APPLICATION_PDF)
            .body(response.getBody());
    }
}

Best practice: In production, inject the API key via @Value from application.properties instead of using environment variables directly. Consider using WebClient for reactive applications or when you need non-blocking I/O.

Error Handling

This reusable client class wraps the API call with proper error handling. The switch expression (Java 14+) provides clean, exhaustive handling of different HTTP status codes.

PixelToPdfClient.java
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class PixelToPdfClient {
    private final HttpClient client = HttpClient.newHttpClient();
    private final String apiKey;

    public PixelToPdfClient(String apiKey) {
        this.apiKey = apiKey;
    }

    public byte[] generatePdf(String source) throws PixelToPdfException {
        try {
            String json = String.format("{\"source\": \"%s\"}", source);

            HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create("https://api.pixeltopdf.com/convert/pdf"))
                .header("X-API-Key", apiKey)
                .header("Content-Type", "application/json")
                .POST(HttpRequest.BodyPublishers.ofString(json))
                .build();

            HttpResponse<byte[]> response = client.send(
                request,
                HttpResponse.BodyHandlers.ofByteArray()
            );

            return switch (response.statusCode()) {
                case 200 -> response.body();
                case 401 -> throw new PixelToPdfException("Invalid API key");
                case 402 -> throw new PixelToPdfException("No credits remaining");
                case 429 -> throw new PixelToPdfException("Rate limit exceeded");
                default -> throw new PixelToPdfException("PDF generation failed");
            };
        } catch (Exception e) {
            throw new PixelToPdfException("Request failed: " + e.getMessage());
        }
    }
}

class PixelToPdfException extends Exception {
    public PixelToPdfException(String message) {
        super(message);
    }
}

Important: The API returns different status codes for different error types: 401 for authentication issues, 402 when you need more credits, and 429 when you've hit the rate limit. Handle each appropriately in production.

Next steps

You've mastered the basics! Learn about headers, footers, page breaks, and advanced styling in our API documentation.