Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
Use - as wkhtmltopdf’s output target, read the process’s standard output through Process.getInputStream(), and copy those bytes to your Java OutputStream. Keep standard error separate, wait for the process, and reject nonzero exit codes. This sends the PDF directly to a ByteArrayOutputStream, servlet response, cloud-upload stream, or another consumer without creating a PDF file first.
The direct command-line pattern
wkhtmltopdf accepts an input file or URL followed by an output path. The special output path - means “write the PDF to stdout.” In shell form:
wkhtmltopdf input.html - > output.pdf
In Java, that stdout pipe appears as Process.getInputStream(). The name can be confusing: it is the child process’s output, exposed as an input stream to your Java program.
Quick wins for a faster PC:
Scan for outdated or missing drivers - takes under a minuteDriver Scan →Clear out junk files and repair common Windows errorsFree Scan →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →An empty output path has a different meaning in the libwkhtmltox settings API: it stores output in a buffer. For a command-line Java integration, use the documented - sentinel and consume the stream.
#1 Best Overall
- Perfect Adobe Acrobat Pro alternative – lifetime license for Windows 10 and 11.
- EDIT text, images, pages, hyperlinks, designs in PDF documents. ORGANIZE PDFs.
- READ and Comment on PDFs – Intuitive reading modes & document commenting and mark up tools!
- CREATE, COMBINE, SCAN and COMPRESS PDFs.
- FILL forms & Digitally Sign PDFs. Work with Digital certificates
A safe Java ProcessBuilder exporter
This exporter accepts the executable path, an input file or URL, and a caller-owned destination stream. It redirects diagnostics to the parent process’s standard error so they cannot contaminate PDF bytes.
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
public final class WkhtmltopdfExporter {
private WkhtmltopdfExporter() {}
public static void export(String executable,
String input,
OutputStream destination)
throws IOException, InterruptedException {
Process process = new ProcessBuilder(List.of(executable, input, "-"))
.redirectError(ProcessBuilder.Redirect.INHERIT)
.start();
try (InputStream pdf = process.getInputStream()) {
pdf.transferTo(destination);
}
int exit = process.waitFor();
if (exit != 0) {
throw new IOException("wkhtmltopdf exited with code " + exit);
}
}
}
Why each part matters
List.of(executable, input, "-")avoids shell quoting and makes the output sentinel explicit.getInputStream()reads only stdout, where the PDF is written.redirectError(INHERIT)keeps warnings and conversion errors out of the PDF stream.transferTocopies bytes without converting them to characters.waitForverifies that wkhtmltopdf completed successfully. A copied stream alone does not prove success.- The destination is not closed: it belongs to the caller. Only the process input stream is closed.
Writing to a ByteArrayOutputStream
Use a byte array when the resulting PDF is modest in size and a later API needs byte[]:
import java.io.ByteArrayOutputStream;
public class Example {
public static void main(String[] args) throws Exception {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
WkhtmltopdfExporter.export("wkhtmltopdf", "input.html", bytes);
byte[] pdfBytes = bytes.toByteArray();
System.out.println("PDF bytes: " + pdfBytes.length);
}
}
Pass an absolute executable path when the Java service has a restricted PATH, for example /usr/local/bin/wkhtmltopdf or the approved Windows installation path. The executable must be installed and executable in the environment where the JVM runs; a Java wrapper does not remove that native dependency.
Do these 3 things before closing this tab:
1Fix the driver behind crashes, sound loss and screen glitches2Repair Windows errors before they cause bigger problems3Scan for outdated or missing drivers - takes under a minuteMemory implications
ByteArrayOutputStream retains the entire document and may grow its backing array while converting. For large or concurrent jobs, stream directly to a file, object-storage upload stream, or HTTP response instead. Do not close a framework-owned destination inside the exporter.
Streaming a PDF from a servlet or HTTP endpoint
Set the response metadata before starting the conversion, then pass the response stream:
response.setContentType("application/pdf");
response.setHeader("Content-Disposition", "inline; filename=report.pdf");
try (OutputStream out = response.getOutputStream()) {
WkhtmltopdfExporter.export("wkhtmltopdf", "input.html", out);
}
Whether to set Content-Length depends on your framework and infrastructure. You do not know the length in advance when wkhtmltopdf is streaming to stdout; chunked transfer or framework buffering may be used instead. If a downstream component requires a seekable stream or a known length, create a temporary file first and serve it after conversion.
Rank #2
- ULTIMATE IMAGE PROCESSNG - GIMP is one of the best known programs for graphic design and image editing
- MAXIMUM FUNCTIONALITY - GIMP has all the functions you need to maniplulate your photos or create original artwork
- MAXIMUM COMPATIBILITY - it's compatible with all the major image editors such as Adobe PhotoShop Elements / Lightroom / CS 5 / CS 6 / PaintShop
- MORE THAN GIMP 2.8 - in addition to the software this package includes ✔ an additional 20,000 clip art images ✔ 10,000 additional photo frames ✔ 900-page PDF manual in English ✔ free e-mail support
- Compatible with Windows PC (11 / 10 / 8.1 / 8 / 7 / Vista and XP) and Mac
Handling stderr, deadlocks, and cancellation
wkhtmltopdf can emit progress, warnings, and errors on stderr. Redirecting stderr with INHERIT is suitable for command-line services. If you need to capture diagnostics, continuously drain process.getErrorStream() on another thread while reading stdout. Do not redirect stderr into stdout: text such as warnings would make the PDF invalid.
Recommended Free Tools
For a request timeout, destroy the process and, where supported by your Java version, use destroyForcibly() after a grace period. Ensure your code closes or cancels the destination according to the surrounding API, and record the command context without logging secrets such as cookies or authorization headers.
Supplying HTML, files, and URLs
Input files and URLs
The command-line synopsis is file/URL oriented, so the simplest reliable input is a controlled HTML file or an approved URL:
wkhtmltopdf https://example.test/invoice/42 -
When constructing arguments in Java, pass each argument as its own list element. Avoid concatenating an entire command string. Validate allowed URL schemes and hosts if users can influence the input; otherwise the converter may access internal services or local files according to its installed security settings.
HTML held in a Java string
If your application starts with an HTML string, materialize it in a controlled temporary file and pass that file’s path, unless the installed wkhtmltopdf build explicitly supports the input mode you require. Use UTF-8 deliberately, apply restrictive file permissions, delete the file in a finally block, and avoid putting untrusted HTML in a shared directory.
JavaScript, assets, cookies, and local files
Rendering options are deployment policy decisions. External stylesheets, fonts, images, JavaScript timing, cookies, custom headers, user-agent selection, and local-file access all affect the result. Use the switches supported by your installed version, and test them in the same container or host image used in production. A page that works in a desktop browser can still fail if resources are inaccessible to the headless process.
Rank #3
- EDIT text, images & designs in PDF documents. ORGANIZE PDFs. Convert PDFs to Word, Excel & ePub.
- READ and Comment PDFs – Intuitive reading modes & document commenting and mark up.
- CREATE, COMBINE, SCAN and COMPRESS PDFs
- FILL forms & Digitally Sign PDFs. PROTECT and Encrypt PDFs
- 1 Year License for 1 Windows & 2 Mobile (Android and/or iOS) devices.
Arguments and a reusable command builder
When you need options, append them before the input and output arguments. This example adds a page size and JavaScript delay; adjust switches to your installed build:
List<String> command = List.of(
"/usr/local/bin/wkhtmltopdf",
"--page-size", "A4",
"--javascript-delay", "500",
"input.html",
"-"
);
Process process = new ProcessBuilder(command)
.redirectError(ProcessBuilder.Redirect.INHERIT)
.start();
Keep option values separate from option names. For user-controlled values, validate and allow-list rather than passing arbitrary switches.
Temporary file versus stdout
| Choose stdout when… | Choose a temporary output file when… |
|---|---|
The next component already accepts an OutputStream. |
A downstream tool requires a filesystem path. |
| You want to avoid a second PDF artifact. | Documents are large and should not accumulate in heap memory. |
| You are returning a response or uploading while conversion runs. | Operations staff need a durable, seekable artifact for later inspection. |
| You can handle an unknown content length. | Your protocol requires a known length before sending bytes. |
Stdout removes the output-file write, but it does not eliminate process startup, rendering, network access, or memory used by wkhtmltopdf itself.
Free tools Windows power users keep installed
One-click scans. No signup required.
Common failures and fixes
“Cannot run program” or permission denied
The executable is missing, not executable, or absent from the JVM’s environment. Install wkhtmltopdf in the runtime image, verify execute permissions, and configure an absolute path.
The PDF is corrupted or starts with warning text
stderr was merged into stdout, or another component wrote to the same stream. Read only getInputStream() for PDF bytes and redirect or drain getErrorStream() separately.
An empty or partial PDF is returned
Inspect stderr and the exit code. Causes include an unreachable URL, blocked resources, JavaScript that never finishes, a timeout, or a process killed during the copy. Do not treat a zero-length or partial byte array as success.
Rank #4
The Java request hangs
A child process can block if stderr is noisy and nobody reads it. Inherit stderr or drain it concurrently. Also enforce a conversion timeout and terminate the process on expiry.
Output works locally but not in production
Compare executable versions, fonts, network routes, sandbox permissions, DNS, certificates, cookies, and local-file policies. Run the exact command inside the production container and preserve diagnostics for a failed job.
Images or CSS are missing
Check URL accessibility from the conversion host, relative paths, TLS trust, authentication headers or cookies, and JavaScript readiness. A browser session’s credentials are not automatically available to wkhtmltopdf.
Wrappers versus direct ProcessBuilder
The wkhtmltopdf-java project provides a Java wrapper with source configuration and saving APIs, but it still requires wkhtmltopdf to be installed. Direct ProcessBuilder is often clearer for this specific streaming requirement because your application controls stdout, stderr, exit status, executable discovery, timeouts, and the destination stream. A wrapper is reasonable when its option model, lifecycle, and error handling match your application.
When to consider a library-native converter
Evaluate alternatives against the requirements that actually matter:
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
- Can conversion write directly to an
OutputStream? - Does it render the HTML, CSS, and JavaScript your pages use?
- Does it remove an external executable or native-library deployment step?
- What are the licensing and operational costs?
- Can you observe warnings, failed resources, and conversion errors?
- How are support and maintenance handled?
PDFreactor is one commercial Java library whose manuals describe Java APIs and direct OutputStream-oriented conversion. That makes it a candidate for teams seeking a library-native architecture, but this does not establish feature parity with wkhtmltopdf; compare your own pages and licensing requirements.
Best Value
- Complete Audio/Visual Lessons
- PDF instruction manual (303 pages)
- Introductory through advanced material for version 2022
- Over 7.5 hours of video lessons (190 individual lessons)
- Quiz, Optional Final Exam, Certificate of Completion
Or skip the browser setup
If your goal is a clean website capture rather than controlling a local wkhtmltopdf process, ScreenshotNeo provides a website screenshot API and MCP server. One GET request returns PNG, JPEG, WebP, or PDF. Cookie and consent banners, newsletter popups, and chat widgets are removed before capture; bot checks, blank pages, failed loads, timeouts, and cache hits are not billed, and response headers report the page verdict and billing status. Its MCP tools—take_screenshot, get_page_info, and capture_pdf—let Claude, Cursor, or another MCP client request captures.
See the ScreenshotNeo API documentation for all options. A PDF request can be as simple as:
curl -G "https://api.screenshotneo.com/v1/shot"
-d access_key=YOUR_API_KEY
--data-urlencode url=https://stripe.com
-o shot.webp
Equivalent JavaScript and Python calls:
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
r.raise_for_status()
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const data = Buffer.from(await res.arrayBuffer());
ScreenshotNeo includes full-page capture, element selectors, device presets, custom viewport and retina scale, PDF paper and margin controls, custom CSS and JavaScript, waits, request blocking, headers and cookies, timezone and geolocation, resizing, chosen-TTL caching, signed links, asynchronous webhooks, bulk capture, usage reporting, and an OpenAPI specification. Every feature is on every plan. The Free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 shots, with yearly billing giving two months free. Create a free ScreenshotNeo account.
Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minuteWindows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallFrequently Asked Questions
Can wkhtmltopdf write directly to Java’s OutputStream?
Yes. Use wkhtmltopdf input.html -, read Process.getInputStream(), and copy the bytes to the destination stream.
Should I use ByteArrayOutputStream for every PDF?
No. It is convenient for small documents, but stream large or concurrent conversions to a file, upload stream, or response to avoid retaining the entire PDF in heap memory.
Why must stderr stay separate?
wkhtmltopdf writes diagnostics to stderr. Mixing that text into stdout corrupts the PDF byte stream.
The Bottom Line
For Java, the reliable pattern is wkhtmltopdf <input> - plus a separately handled stderr stream, explicit process waiting, and nonzero-exit failure handling. Choose a temporary file when you need a seekable artifact or cannot hold the document in memory.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

