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.");
}
}
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();
}
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();
}
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);
}
}
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();
}
Try it free — 100 requests/month, no credit card. → Get started in 2 minutes
Top comments (0)