DEV Community

Custodia-Admin
Custodia-Admin

Posted on • Originally published at pagebolt.dev

How to take screenshots and generate PDFs in Java

How to Take Screenshots and Generate PDFs in Java

Java doesn't have a native headless browser. Teams that need screenshots or PDFs typically reach for Selenium WebDriver (which requires ChromeDriver), Flying Saucer (renders XHTML, not modern HTML), or iText/Apache PDFBox (programmatic PDF generation, not HTML capture). All three involve significant setup.

Here's the simpler path: one HTTP call, binary response, standard HttpClient.

Screenshot from a URL (Java 11+)

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 PageBoltClient {

    private static final String API_KEY = System.getenv("PAGEBOLT_API_KEY");
    private static final String BASE_URL = "https://pagebolt.dev/api/v1";
    private final HttpClient client = HttpClient.newHttpClient();

    public byte[] screenshot(String url) throws Exception {
        String body = String.format(
            "{\"url\":\"%s\",\"fullPage\":true,\"blockBanners\":true}", url
        );

        HttpRequest request = HttpRequest.newBuilder()
            .uri(URI.create(BASE_URL + "/screenshot"))
            .header("x-api-key", API_KEY)
            .header("Content-Type", "application/json")
            .POST(HttpRequest.BodyPublishers.ofString(body))
            .build();

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

    public static void main(String[] args) throws Exception {
        PageBoltClient pagebolt = new PageBoltClient();
        byte[] image = pagebolt.screenshot("https://example.com");
        Files.write(Path.of("screenshot.png"), image);
        System.out.println("Screenshot saved.");
    }
}
Enter fullscreen mode Exit fullscreen mode

PDF from a URL

public byte[] pdfFromUrl(String url) throws Exception {
    String body = String.format(
        "{\"url\":\"%s\",\"blockBanners\":true}", url
    );

    HttpRequest request = HttpRequest.newBuilder()
        .uri(URI.create(BASE_URL + "/pdf"))
        .header("x-api-key", API_KEY)
        .header("Content-Type", "application/json")
        .POST(HttpRequest.BodyPublishers.ofString(body))
        .build();

    return client.send(request, HttpResponse.BodyHandlers.ofByteArray()).body();
}
Enter fullscreen mode Exit fullscreen mode

PDF from HTML (replacing Flying Saucer / iText)

public byte[] pdfFromHtml(String html) throws Exception {
    // Escape HTML for JSON
    String escapedHtml = html
        .replace("\\", "\\\\")
        .replace("\"", "\\\"")
        .replace("\n", "\\n")
        .replace("\r", "\\r");

    String body = "{\"html\":\"" + escapedHtml + "\"}";

    HttpRequest request = HttpRequest.newBuilder()
        .uri(URI.create(BASE_URL + "/pdf"))
        .header("x-api-key", API_KEY)
        .header("Content-Type", "application/json")
        .POST(HttpRequest.BodyPublishers.ofString(body))
        .build();

    return client.send(request, HttpResponse.BodyHandlers.ofByteArray()).body();
}
Enter fullscreen mode Exit fullscreen mode

For production use, prefer a JSON library (Jackson or Gson) to serialize the body — avoids manual escaping issues with complex HTML templates.

Spring Boot controller

import org.springframework.web.bind.annotation.*;
import org.springframework.http.*;

@RestController
@RequestMapping("/api/invoices")
public class InvoiceController {

    private final PageBoltClient pagebolt = new PageBoltClient();

    @GetMapping("/{id}/pdf")
    public ResponseEntity<byte[]> downloadPdf(@PathVariable Long id) throws Exception {
        Invoice invoice = invoiceService.findById(id);
        String html = templateEngine.render("invoice", invoice);

        byte[] pdf = pagebolt.pdfFromHtml(html);

        return ResponseEntity.ok()
            .header(HttpHeaders.CONTENT_TYPE, "application/pdf")
            .header(HttpHeaders.CONTENT_DISPOSITION,
                "attachment; filename=\"invoice-" + id + ".pdf\"")
            .body(pdf);
    }
}
Enter fullscreen mode Exit fullscreen mode

No Selenium, no ChromeDriver, no WebDriver setup. The HttpClient used here ships with Java 11+ — no additional dependencies.

With Jackson (recommended for production)

import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.Map;

public byte[] screenshot(String url) throws Exception {
    ObjectMapper mapper = new ObjectMapper();
    String body = mapper.writeValueAsString(Map.of(
        "url", url,
        "fullPage", true,
        "blockBanners", true
    ));

    HttpRequest request = HttpRequest.newBuilder()
        .uri(URI.create(BASE_URL + "/screenshot"))
        .header("x-api-key", API_KEY)
        .header("Content-Type", "application/json")
        .POST(HttpRequest.BodyPublishers.ofString(body))
        .build();

    return client.send(request, HttpResponse.BodyHandlers.ofByteArray()).body();
}
Enter fullscreen mode Exit fullscreen mode

Try it free — 100 requests/month, no credit card. → Get started in 2 minutes

Top comments (0)