How to Convert HTML to PDF using IronPDF for JAVA

HTML to PDF in Java

IronPDF for Java converts HTML content into PDF documents by running a full Chromium rendering engine — the same engine that powers modern browsers. Every CSS property, font, image, and JavaScript-generated layout renders exactly as it would in a browser window, then lands on the page as a pixel-accurate PDF.

This tutorial walks through the three core conversion methods: HTML string to PDF, live URL to PDF, and local HTML file to PDF. It also covers installation, license configuration, and the rendering options developers reach for most often.

The Java library mirrors the API shape of IronPDF for .NET, so teams working across both runtimes will find the transition straightforward. Source code for all examples in this tutorial is available on GitHub.

Quickstart: Convert HTML to PDF in Java

Add IronPDF to your Maven pom.xml, then call a single method to produce a PDF:

//:path=/static-assets/pdf/content-code-examples/tutorials/html-to-pdf/quickstart.java
import com.ironsoftware.ironpdf.*;

// Set your license key before any rendering calls
License.setLicenseKey("YOUR-LICENSE-KEY");

// Convert an HTML string to a PDF and save it
PdfDocument pdf = PdfDocument.renderHtmlAsPdf("<h1>Hello from IronPDF for Java!</h1>");
pdf.saveAs("output.pdf");
//:path=/static-assets/pdf/content-code-examples/tutorials/html-to-pdf/quickstart.java
import com.ironsoftware.ironpdf.*;

// Set your license key before any rendering calls
License.setLicenseKey("YOUR-LICENSE-KEY");

// Convert an HTML string to a PDF and save it
PdfDocument pdf = PdfDocument.renderHtmlAsPdf("<h1>Hello from IronPDF for Java!</h1>");
pdf.saveAs("output.pdf");
JAVA

Start using IronPDF in your project today with a free trial.

First Step:
green arrow pointer

Table of Contents


Installing IronPDF for Java

IronPDF for Java ships through Maven Central and as a standalone JAR. The Maven route is recommended for most projects because it handles transitive dependencies and keeps library versions consistent across developer machines and CI pipelines.

Option 1: Add IronPDF as a Maven Dependency

Open the project's pom.xml file and add the following entries to the <dependencies> block:

//:path=/static-assets/pdf/content-code-examples/tutorials/html-to-pdf/maven-dependency.xml
<dependencies>

    <dependency>
        <groupId>com.ironsoftware</groupId>
        <artifactId>ironpdf</artifactId>
        <version>[LATEST_VERSION]</version>
    </dependency>

    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-simple</artifactId>
        <version>[LATEST_VERSION]</version>
    </dependency>
</dependencies>
//:path=/static-assets/pdf/content-code-examples/tutorials/html-to-pdf/maven-dependency.xml
<dependencies>

    <dependency>
        <groupId>com.ironsoftware</groupId>
        <artifactId>ironpdf</artifactId>
        <version>[LATEST_VERSION]</version>
    </dependency>

    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-simple</artifactId>
        <version>[LATEST_VERSION]</version>
    </dependency>
</dependencies>
XML

The first artifact pulls in the latest IronPDF for Java release. The second artifact activates SLF4J logging so that IronPDF's rendering engine can write diagnostic messages during execution. Developers who prefer Logback or Log4J can substitute that provider instead. The logging dependency is optional — omit it if logs are not needed.

After saving the file, run mvn install from the project's root directory to download both libraries. Maven resolves the full dependency graph automatically, including any transitive dependencies that IronPDF requires.

For Gradle projects, the equivalent dependency declaration in build.gradle is:

//:path=/static-assets/pdf/content-code-examples/tutorials/html-to-pdf/gradle-dependency.java
// build.gradle (Groovy DSL)
// dependencies {
//     implementation 'com.ironsoftware:ironpdf:[LATEST_VERSION]'
//     implementation 'org.slf4j:slf4j-simple:[LATEST_VERSION]'
// }
//:path=/static-assets/pdf/content-code-examples/tutorials/html-to-pdf/gradle-dependency.java
// build.gradle (Groovy DSL)
// dependencies {
//     implementation 'com.ironsoftware:ironpdf:[LATEST_VERSION]'
//     implementation 'org.slf4j:slf4j-simple:[LATEST_VERSION]'
// }
JAVA

Replace [LATEST_VERSION] with the version number from the IronPDF changelog or from the Maven Central page for the artifact.

Option 2: Add the JAR File Manually

Download the IronPDF JAR directly from Maven Central and add it to the project's classpath. This approach works without a build tool but requires manual version management, so it is best suited for legacy projects that do not use Maven or Gradle, or for environments where outbound network access is restricted.

After downloading, add the JAR to the project's classpath through the IDE's project settings. In IntelliJ IDEA, right-click the project root, select "Open Module Settings," navigate to "Dependencies," and add the JAR file. In Eclipse, right-click the project, go to "Properties > Java Build Path > Libraries," then click "Add External JARs."

Please noteThe IronPDF JAR includes a bundled Chromium engine binary. The first rendering call on a new machine will extract it to a temp directory, which takes a few seconds. Subsequent calls use the cached binary and start instantly. In containerized environments, mount a persistent volume at the extraction path to avoid re-extraction on every container startup.

System Requirements

IronPDF for Java runs on JDK 8 or later. It supports Windows, Linux, and macOS on both x86-64 and ARM64 architectures. No external browser installation is required — the Chromium binary is bundled with the JAR. On Linux, ensure that the standard shared libraries expected by Chromium are present. The IronPDF for Java documentation lists the minimum required packages for common Linux distributions.


How Do I Import IronPDF and Configure a License Key?

Every IronPDF class lives in the com.ironsoftware.ironpdf package. Import it at the top of any source file that will create or manipulate PDF documents.

//:path=/static-assets/pdf/content-code-examples/tutorials/html-to-pdf/import-and-license.java
import com.ironsoftware.ironpdf.*;
import java.nio.file.Paths;

// Apply your license key before any other IronPDF calls
License.setLicenseKey("YOUR-LICENSE-KEY");

// Optional: set a custom log file path
Settings.setLogPath(Paths.get("IronPdfEngine.log"));
//:path=/static-assets/pdf/content-code-examples/tutorials/html-to-pdf/import-and-license.java
import com.ironsoftware.ironpdf.*;
import java.nio.file.Paths;

// Apply your license key before any other IronPDF calls
License.setLicenseKey("YOUR-LICENSE-KEY");

// Optional: set a custom log file path
Settings.setLogPath(Paths.get("IronPdfEngine.log"));
JAVA

Without a license key, IronPDF runs in trial mode and stamps each PDF page with a tiled watermark. Setting the key removes the watermark and unlocks all features. Start a free trial to obtain a key immediately.

IronPDF trial-mode watermark stamped across a rendered PDF page

The license key is a string that Iron Software issues when a trial or commercial license is activated. Store it in an environment variable or a configuration file rather than hardcoding it in source code. A common pattern is to read it from an environment variable at startup:

//:path=/static-assets/pdf/content-code-examples/tutorials/html-to-pdf/license-from-env.java
import com.ironsoftware.ironpdf.*;

// Read the license key from an environment variable
String licenseKey = System.getenv("IRONPDF_LICENSE_KEY");
if (licenseKey != null && !licenseKey.isEmpty()) {
    License.setLicenseKey(licenseKey);
}
//:path=/static-assets/pdf/content-code-examples/tutorials/html-to-pdf/license-from-env.java
import com.ironsoftware.ironpdf.*;

// Read the license key from an environment variable
String licenseKey = System.getenv("IRONPDF_LICENSE_KEY");
if (licenseKey != null && !licenseKey.isEmpty()) {
    License.setLicenseKey(licenseKey);
}
JAVA

This approach keeps the key out of version control and makes it straightforward to use different keys across development, staging, and production environments.

ImportantLicense.setLicenseKey and Settings.setLogPath must both be called before any rendering or manipulation method. Place them at application startup — ideally in a static initializer block or a main entry point.


How Do I Convert an HTML String to PDF?

PdfDocument.renderHtmlAsPdf accepts a string of HTML markup and returns a PdfDocument object that can be saved, merged, or modified before writing to disk. This is the primary method for programmatically generated HTML — for example, reports built by combining database values with an HTML template defined as a Java string or loaded from a file.

//:path=/static-assets/pdf/content-code-examples/tutorials/html-to-pdf/html-string-to-pdf.java
import com.ironsoftware.ironpdf.*;

// Simple one-liner: convert an HTML string to a PDF
PdfDocument pdf = PdfDocument.renderHtmlAsPdf("<h1>Hello from IronPDF!</h1>");
pdf.saveAs("htmlstring_to_pdf.pdf");
//:path=/static-assets/pdf/content-code-examples/tutorials/html-to-pdf/html-string-to-pdf.java
import com.ironsoftware.ironpdf.*;

// Simple one-liner: convert an HTML string to a PDF
PdfDocument pdf = PdfDocument.renderHtmlAsPdf("<h1>Hello from IronPDF!</h1>");
pdf.saveAs("htmlstring_to_pdf.pdf");
JAVA

The rendering engine resolves relative asset paths (images, stylesheets, scripts) against the optional second argument — the base path. When a base path is provided, the engine treats it as the root from which relative URLs are resolved. This allows HTML that references local CSS and image files to render correctly without any path manipulation in the source markup.

//:path=/static-assets/pdf/content-code-examples/tutorials/html-to-pdf/html-string-with-assets.java
import com.ironsoftware.ironpdf.*;

// HTML references assets in a local "assets" subfolder
String html = "<html>" +
    "<head><link rel='stylesheet' href='assets/style.css'></head>" +
    "<body><h1>Invoice</h1><img src='assets/logo.png' /></body>" +
    "</html>";

// Pass the base path so IronPDF resolves relative asset URLs
PdfDocument pdf = PdfDocument.renderHtmlAsPdf(html, "C:/my-project/templates");
pdf.saveAs("invoice.pdf");
//:path=/static-assets/pdf/content-code-examples/tutorials/html-to-pdf/html-string-with-assets.java
import com.ironsoftware.ironpdf.*;

// HTML references assets in a local "assets" subfolder
String html = "<html>" +
    "<head><link rel='stylesheet' href='assets/style.css'></head>" +
    "<body><h1>Invoice</h1><img src='assets/logo.png' /></body>" +
    "</html>";

// Pass the base path so IronPDF resolves relative asset URLs
PdfDocument pdf = PdfDocument.renderHtmlAsPdf(html, "C:/my-project/templates");
pdf.saveAs("invoice.pdf");
JAVA

The saveAs method accepts an absolute or relative path. The library creates the file if it does not exist and overwrites it if it does. When writing to a directory that the application may not have created yet, create the directory first using Files.createDirectories(Paths.get("output")) before calling saveAs.

IronPDF supports the full HTML5 and CSS3 feature set as implemented in Chromium. Custom fonts loaded via @font-face in CSS render correctly when the font files are accessible at the base path. SVG elements and <canvas> elements rendered by JavaScript also appear in the PDF output.

TipsKeep HTML templates in a dedicated directory and pass that directory as the base path. This pattern lets designers update the template without touching any Java code.


How Do I Convert a URL to PDF in Java?

PdfDocument.renderUrlAsPdf fetches the page at the given URL, waits for JavaScript to execute and dynamic content to load, then converts the fully rendered DOM into a PDF.

//:path=/static-assets/pdf/content-code-examples/tutorials/html-to-pdf/url-to-pdf.java
import com.ironsoftware.ironpdf.*;

// Convert a live web page to PDF
PdfDocument pdf = PdfDocument.renderUrlAsPdf("https://en.wikipedia.org/wiki/PDF");
pdf.saveAs("wikipedia_pdf_article.pdf");
//:path=/static-assets/pdf/content-code-examples/tutorials/html-to-pdf/url-to-pdf.java
import com.ironsoftware.ironpdf.*;

// Convert a live web page to PDF
PdfDocument pdf = PdfDocument.renderUrlAsPdf("https://en.wikipedia.org/wiki/PDF");
pdf.saveAs("wikipedia_pdf_article.pdf");
JAVA

The engine handles authentication headers, cookies, and JavaScript-heavy single-page applications. For pages that require a login or custom request headers, use the ChromePdfRenderOptions class to configure request parameters before calling renderUrlAsPdf.

This conversion method is useful for archiving web pages, generating compliance snapshots, and producing client-facing reports from internal dashboards. Server-generated pages accessed over a local network are fully supported — pass http://localhost:8080/report/123 in the same way as a public URL. IronPDF will wait for the page to load completely before rendering, so dashboards that rely on asynchronous data fetches render with their data populated rather than with empty charts.

For pages behind HTTP basic authentication, pass credentials in the URL using the http://user:password@host/path format. For pages protected by session cookies, configure the cookie jar on the ChromePdfRenderOptions object before passing it to renderUrlAsPdf. See the IronPDF for Java documentation for details on configuring request headers and managing cookies for authenticated URLs.


How Do I Convert a Local HTML File to PDF?

PdfDocument.renderHtmlFileAsPdf reads an HTML file from the local file system and renders it to PDF. All linked assets (CSS, JavaScript, images) referenced by relative paths in the file are resolved relative to the HTML file's own directory.

//:path=/static-assets/pdf/content-code-examples/tutorials/html-to-pdf/html-file-to-pdf.java
import com.ironsoftware.ironpdf.*;

// Convert a local HTML file — assets resolve relative to its directory
PdfDocument pdf = PdfDocument.renderHtmlFileAsPdf("C:/invoices/TestInvoice1.html");
pdf.saveAs("htmlfile_to_pdf.pdf");
//:path=/static-assets/pdf/content-code-examples/tutorials/html-to-pdf/html-file-to-pdf.java
import com.ironsoftware.ironpdf.*;

// Convert a local HTML file — assets resolve relative to its directory
PdfDocument pdf = PdfDocument.renderHtmlFileAsPdf("C:/invoices/TestInvoice1.html");
pdf.saveAs("htmlfile_to_pdf.pdf");
JAVA

This approach is the most accurate for converting complex HTML documents. Because the rendering engine operates on the file system path rather than an in-memory string, relative references to multi-level asset directories resolve without any additional configuration. A template that relies on a style.css and script.js in the same folder will render correctly without any path adjustments.

This method is particularly well-suited for invoice generation, contract production, and any workflow where a designer maintains the HTML template independently of the Java application. The development team treats the template as a data file, stores it alongside the application, and calls renderHtmlFileAsPdf with the path. When the designer updates the template to change branding or layout, no Java code changes are required.

Please noteIronPDF supports all modern HTML and CSS features that Chromium supports — Flexbox, CSS Grid, CSS variables, Web fonts, and media queries all render correctly in the output PDF.


How Do I Set PDF Generation Options?

ChromePdfRenderOptions controls rendering behavior: paper size, margins, zoom level, print media type, JavaScript timeout, and more. Create an instance, configure the desired properties, and pass it as the second argument to any render*AsPdf method.

//:path=/static-assets/pdf/content-code-examples/tutorials/html-to-pdf/render-options.java
import com.ironsoftware.ironpdf.*;
import com.ironsoftware.ironpdf.render.*;

ChromePdfRenderOptions options = new ChromePdfRenderOptions();

// Render the page using the print media type (uses @media print CSS rules)
options.setCssMediaType(CssMediaType.PRINT);

// Wait up to 5 seconds for JavaScript to finish executing
options.setJavascriptTimeout(5000);

// Apply a 1.5x zoom level to scale content to fit the page
options.setZoom(150);

// Render at 150 DPI for sharper images in print output
options.setDpi(150);

PdfDocument pdf = PdfDocument.renderHtmlAsPdf(
    "<h1>Styled Report</h1>",
    options
);
pdf.saveAs("styled_report.pdf");
//:path=/static-assets/pdf/content-code-examples/tutorials/html-to-pdf/render-options.java
import com.ironsoftware.ironpdf.*;
import com.ironsoftware.ironpdf.render.*;

ChromePdfRenderOptions options = new ChromePdfRenderOptions();

// Render the page using the print media type (uses @media print CSS rules)
options.setCssMediaType(CssMediaType.PRINT);

// Wait up to 5 seconds for JavaScript to finish executing
options.setJavascriptTimeout(5000);

// Apply a 1.5x zoom level to scale content to fit the page
options.setZoom(150);

// Render at 150 DPI for sharper images in print output
options.setDpi(150);

PdfDocument pdf = PdfDocument.renderHtmlAsPdf(
    "<h1>Styled Report</h1>",
    options
);
pdf.saveAs("styled_report.pdf");
JAVA

The CssMediaType.PRINT setting tells the engine to apply @media print CSS rules, which many HTML templates use to hide navigation bars and apply print-specific layouts. The setJavascriptTimeout method is important for pages that use JavaScript charting libraries (D3.js, Chart.js) or lazy-loading content — if the timeout is too short, the PDF will capture the page before JavaScript finishes rendering, producing empty charts or missing sections. Increase the timeout if the rendered PDF is missing expected content.

The setDpi method controls image resolution in the output. The default (96 DPI) is appropriate for on-screen documents. For PDFs that will be printed or displayed on high-DPI displays, use 150 or 300 DPI. Higher DPI values increase file size proportionally. See the PDF generation settings code example for the full list of configurable properties.


How Do I Add Headers and Footers?

IronPDF supports both text-based and HTML-based headers and footers. Text headers use a TextHeaderFooter object with format tokens ({page}, {total-pages}, {date}) that resolve automatically at render time.

//:path=/static-assets/pdf/content-code-examples/tutorials/html-to-pdf/headers-footers.java
import com.ironsoftware.ironpdf.*;
import com.ironsoftware.ironpdf.headerfooter.*;

// Create a text-based header and footer
TextHeaderFooter header = new TextHeaderFooter();
header.setCenterText("Confidential — {date}");
header.setFontSize(10);

TextHeaderFooter footer = new TextHeaderFooter();
footer.setLeftText("My Company, Inc.");
footer.setRightText("Page {page} of {total-pages}");
footer.setFontSize(9);

PdfDocument pdf = PdfDocument.renderHtmlAsPdf("<h1>Annual Report</h1>");
pdf.addTextHeaders(header);
pdf.addTextFooters(footer);
pdf.saveAs("report_with_headers.pdf");
//:path=/static-assets/pdf/content-code-examples/tutorials/html-to-pdf/headers-footers.java
import com.ironsoftware.ironpdf.*;
import com.ironsoftware.ironpdf.headerfooter.*;

// Create a text-based header and footer
TextHeaderFooter header = new TextHeaderFooter();
header.setCenterText("Confidential — {date}");
header.setFontSize(10);

TextHeaderFooter footer = new TextHeaderFooter();
footer.setLeftText("My Company, Inc.");
footer.setRightText("Page {page} of {total-pages}");
footer.setFontSize(9);

PdfDocument pdf = PdfDocument.renderHtmlAsPdf("<h1>Annual Report</h1>");
pdf.addTextHeaders(header);
pdf.addTextFooters(footer);
pdf.saveAs("report_with_headers.pdf");
JAVA

The {page} and {total-pages} tokens produce values like "3 of 12" in the footer and update automatically as the page count changes, so there is no need to know the final page count before rendering. The {date} token inserts the current date using the system locale. Other available tokens include {time}, {document-title}, and {url}.

Headers and footers added with addTextHeaders and addTextFooters apply to every page in the document by default. Pass the optional page range parameter to restrict them to specific pages — for example, to skip the header on the cover page.

For styled headers that require logos, brand colors, or custom layouts, use HtmlHeaderFooter instead — it accepts a full HTML string and renders it the same way as the page body. See the custom headers and footers example for the full HTML header pattern.


How Do I Set Page Margins and Paper Size?

Pass a ChromePdfRenderOptions instance with margin and paper size values configured before calling any render*AsPdf method.

//:path=/static-assets/pdf/content-code-examples/tutorials/html-to-pdf/margins-paper-size.java
import com.ironsoftware.ironpdf.*;
import com.ironsoftware.ironpdf.render.*;
import com.ironsoftware.ironpdf.page.*;

ChromePdfRenderOptions options = new ChromePdfRenderOptions();

// Set uniform margins in millimeters
options.setMarginTop(20);
options.setMarginBottom(20);
options.setMarginLeft(15);
options.setMarginRight(15);

// Use A4 paper (default is Letter)
options.setPaperSize(PaperSize.A4);

PdfDocument pdf = PdfDocument.renderHtmlAsPdf("<p>Page content here.</p>", options);
pdf.saveAs("a4_with_margins.pdf");
//:path=/static-assets/pdf/content-code-examples/tutorials/html-to-pdf/margins-paper-size.java
import com.ironsoftware.ironpdf.*;
import com.ironsoftware.ironpdf.render.*;
import com.ironsoftware.ironpdf.page.*;

ChromePdfRenderOptions options = new ChromePdfRenderOptions();

// Set uniform margins in millimeters
options.setMarginTop(20);
options.setMarginBottom(20);
options.setMarginLeft(15);
options.setMarginRight(15);

// Use A4 paper (default is Letter)
options.setPaperSize(PaperSize.A4);

PdfDocument pdf = PdfDocument.renderHtmlAsPdf("<p>Page content here.</p>", options);
pdf.saveAs("a4_with_margins.pdf");
JAVA

Margin values are in millimeters. The PaperSize enum covers standard sizes (A4, Letter, Legal, A3, and others). Developers who need non-standard dimensions can set a custom width and height using options.setCustomPaperWidth and options.setCustomPaperHeight. The custom paper size example and custom margins example show the full configuration patterns.


How Do I Apply a Watermark to a PDF?

A watermark in IronPDF is HTML stamped over each page at a configurable opacity. This approach gives developers full control over the watermark's appearance — any HTML element, image, or styled text can serve as the stamp.

//:path=/static-assets/pdf/content-code-examples/tutorials/html-to-pdf/watermark.java
import com.ironsoftware.ironpdf.*;

PdfDocument pdf = PdfDocument.renderHtmlAsPdf("<h1>Confidential Report</h1><p>Internal use only.</p>");

// Define the watermark using an HTML string
String watermarkHtml = "<h1 style='color:rgba(200,0,0,0.3); transform:rotate(-45deg);'>DRAFT</h1>";

// Stamp the watermark on all pages at 50% opacity
pdf.applyStamp(watermarkHtml);

pdf.saveAs("draft_watermark.pdf");
//:path=/static-assets/pdf/content-code-examples/tutorials/html-to-pdf/watermark.java
import com.ironsoftware.ironpdf.*;

PdfDocument pdf = PdfDocument.renderHtmlAsPdf("<h1>Confidential Report</h1><p>Internal use only.</p>");

// Define the watermark using an HTML string
String watermarkHtml = "<h1 style='color:rgba(200,0,0,0.3); transform:rotate(-45deg);'>DRAFT</h1>";

// Stamp the watermark on all pages at 50% opacity
pdf.applyStamp(watermarkHtml);

pdf.saveAs("draft_watermark.pdf");
JAVA

The applyStamp method accepts an HtmlStampOptions parameter for precise positioning — center, top-left, custom pixel offsets, and z-index (foreground or background). Setting the stamp as a background places it behind text so that the document remains readable. Setting it as a foreground places it on top, which is more difficult to obscure when printing.

TipsTo produce a repeating tile watermark — the kind IronPDF itself applies in trial mode — render a grid of rotated text elements in the HTML stamp string and size the element to fill the entire page.

See the custom watermark how-to guide for examples covering background watermarks, tiled patterns, and removing watermarks by upgrading the license.


How Do I Merge Multiple PDFs into One?

PdfDocument.merge combines two or more PdfDocument objects in order and returns a single new document. This is the preferred approach for assembling reports from component sections, appending cover pages, or stitching together per-user sections of a batch job.

//:path=/static-assets/pdf/content-code-examples/tutorials/html-to-pdf/merge-pdfs.java
import com.ironsoftware.ironpdf.*;
import java.util.Arrays;
import java.util.List;

// Render two separate HTML documents into PDFs
PdfDocument cover    = PdfDocument.renderHtmlAsPdf("<h1>Cover Page</h1>");
PdfDocument body     = PdfDocument.renderHtmlAsPdf("<h1>Report Body</h1><p>Section one...</p>");
PdfDocument appendix = PdfDocument.renderHtmlAsPdf("<h2>Appendix A</h2>");

// Merge all three into a single PDF in the specified order
List<PdfDocument> parts = Arrays.asList(cover, body, appendix);
PdfDocument merged = PdfDocument.merge(parts);
merged.saveAs("full_report.pdf");
//:path=/static-assets/pdf/content-code-examples/tutorials/html-to-pdf/merge-pdfs.java
import com.ironsoftware.ironpdf.*;
import java.util.Arrays;
import java.util.List;

// Render two separate HTML documents into PDFs
PdfDocument cover    = PdfDocument.renderHtmlAsPdf("<h1>Cover Page</h1>");
PdfDocument body     = PdfDocument.renderHtmlAsPdf("<h1>Report Body</h1><p>Section one...</p>");
PdfDocument appendix = PdfDocument.renderHtmlAsPdf("<h2>Appendix A</h2>");

// Merge all three into a single PDF in the specified order
List<PdfDocument> parts = Arrays.asList(cover, body, appendix);
PdfDocument merged = PdfDocument.merge(parts);
merged.saveAs("full_report.pdf");
JAVA

Pages from each source document appear in the merged output in the order that the source list specifies. The merged document inherits no metadata from any individual source — update meta.title and other document properties using PdfDocument.getPdfMetaData() after merging if those fields matter to the downstream consumer.

The merge method also has a two-argument overload that accepts exactly two PdfDocument instances. For bulk merges of many documents, use the list overload — it is more efficient than chaining multiple two-argument calls because it processes all sources in a single pass.

Please noteEach source PdfDocument in the merge list remains valid and unchanged after the call. The merged instance is a new, independent document. Release source documents with their close() method when no longer needed to free the associated native resources.


How Do I Add or Remove Pages from a PDF?

Individual pages can be copied out of one document into another, or deleted outright, using the PdfDocument.copyPage, PdfDocument.copyPages, and PdfDocument.removePages methods.

//:path=/static-assets/pdf/content-code-examples/tutorials/html-to-pdf/page-operations.java
import com.ironsoftware.ironpdf.*;
import java.util.Arrays;

// Generate a multi-page document using CSS page breaks
PdfDocument report = PdfDocument.renderHtmlAsPdf(
    "<p>Page 1 content</p>" +
    "<div style='page-break-after:always;'></div>" +
    "<p>Page 2 content</p>" +
    "<div style='page-break-after:always;'></div>" +
    "<p>Page 3 content</p>"
);

// Remove page 2 (zero-indexed — page index 1)
report.removePages(Arrays.asList(1));

// Save the two-page result
report.saveAs("two_page_report.pdf");
//:path=/static-assets/pdf/content-code-examples/tutorials/html-to-pdf/page-operations.java
import com.ironsoftware.ironpdf.*;
import java.util.Arrays;

// Generate a multi-page document using CSS page breaks
PdfDocument report = PdfDocument.renderHtmlAsPdf(
    "<p>Page 1 content</p>" +
    "<div style='page-break-after:always;'></div>" +
    "<p>Page 2 content</p>" +
    "<div style='page-break-after:always;'></div>" +
    "<p>Page 3 content</p>"
);

// Remove page 2 (zero-indexed — page index 1)
report.removePages(Arrays.asList(1));

// Save the two-page result
report.saveAs("two_page_report.pdf");
JAVA

Page indices in IronPDF are zero-based. When removing multiple pages, pass all indices in a single removePages call rather than calling it multiple times in a loop, because each removal shifts subsequent page indices. Passing the full list at once avoids index drift. For example, to remove pages 2 and 4 from a five-page document, pass Arrays.asList(1, 3) — not two separate calls.

To insert pages from an external PDF — for example, appending a legal disclosure from a static template — use PdfDocument.insertPdf to splice the external document at a specific position. The page count of the receiving document updates immediately after the insertion.

The css page-break-after:always CSS property is the standard way to force page breaks in HTML that will be rendered to PDF. IronPDF also supports the newer break-after: page CSS property. Both approaches produce predictable page breaks without requiring any special Java code.


How Do I Password-Protect a PDF in Java?

IronPDF supports two distinct passwords on a PDF: an owner password that controls editing, printing, and copying permissions, and a user password that controls document opening. Both are set through the SecurityOptions class.

//:path=/static-assets/pdf/content-code-examples/tutorials/html-to-pdf/password-protect.java
import com.ironsoftware.ironpdf.*;
import com.ironsoftware.ironpdf.security.*;

PdfDocument pdf = PdfDocument.renderHtmlAsPdf("<h1>Secure Document</h1>");

SecurityOptions security = new SecurityOptions();

// Require a password to open the document
security.setUserPassword("user123");

// Require a separate password to edit, print, or copy content
security.setOwnerPassword("owner456");

// Restrict printing to prevent unauthorized reproduction
security.setAllowUserPrinting(PrintOptions.FullPrintQuality);

PdfSecurityManager securityManager = new PdfSecurityManager(pdf);
securityManager.setSecurityOptions(security);

pdf.saveAs("secure_document.pdf");
//:path=/static-assets/pdf/content-code-examples/tutorials/html-to-pdf/password-protect.java
import com.ironsoftware.ironpdf.*;
import com.ironsoftware.ironpdf.security.*;

PdfDocument pdf = PdfDocument.renderHtmlAsPdf("<h1>Secure Document</h1>");

SecurityOptions security = new SecurityOptions();

// Require a password to open the document
security.setUserPassword("user123");

// Require a separate password to edit, print, or copy content
security.setOwnerPassword("owner456");

// Restrict printing to prevent unauthorized reproduction
security.setAllowUserPrinting(PrintOptions.FullPrintQuality);

PdfSecurityManager securityManager = new PdfSecurityManager(pdf);
securityManager.setSecurityOptions(security);

pdf.saveAs("secure_document.pdf");
JAVA

The AllowUserPrinting setting accepts a PrintOptions enum: FullPrintQuality, LowQualityPrint, or NoPrint. When the owner password is set but the user password is left empty, the document opens without a password but editing and other operations require the owner password in a PDF editor.

WarningPDF password protection encrypts the file but is not a substitute for proper access control systems. Determined users with specialized tools can attempt brute-force attacks on weak passwords. Use strong, randomly generated passwords for documents that require genuine security.


How Do I Convert an HTML Template with Dynamic Data?

Generating PDFs from a data-driven HTML template is one of the most common production use cases for IronPDF. The standard approach is to build the HTML string in Java using a templating library or string operations, then pass the finished string to renderHtmlAsPdf.

//:path=/static-assets/pdf/content-code-examples/tutorials/html-to-pdf/dynamic-template.java
import com.ironsoftware.ironpdf.*;

// Simulate data from a database or service layer
String customerName  = "Acme Corp";
String invoiceNumber = "INV-20240501";
String totalAmount   = "$1,250.00";
String dueDate       = "2024-06-01";

// Build the HTML template with real data injected
String html = "<!DOCTYPE html><html><head>" +
    "<style>body{font-family:Arial,sans-serif;margin:40px;}" +
    "table{width:100%;border-collapse:collapse;}" +
    "th,td{border:1px solid #ccc;padding:8px;text-align:left;}" +
    "th{background:#f4f4f4;}</style></head><body>" +
    "<h1>Invoice</h1>" +
    "<p><strong>Customer:</strong> " + customerName + "</p>" +
    "<p><strong>Invoice #:</strong> " + invoiceNumber + "</p>" +
    "<table><tr><th>Description</th><th>Amount</th></tr>" +
    "<tr><td>Professional Services</td><td>" + totalAmount + "</td></tr>" +
    "</table>" +
    "<p><strong>Due Date:</strong> " + dueDate + "</p>" +
    "</body></html>";

PdfDocument pdf = PdfDocument.renderHtmlAsPdf(html);
pdf.saveAs(invoiceNumber + ".pdf");
//:path=/static-assets/pdf/content-code-examples/tutorials/html-to-pdf/dynamic-template.java
import com.ironsoftware.ironpdf.*;

// Simulate data from a database or service layer
String customerName  = "Acme Corp";
String invoiceNumber = "INV-20240501";
String totalAmount   = "$1,250.00";
String dueDate       = "2024-06-01";

// Build the HTML template with real data injected
String html = "<!DOCTYPE html><html><head>" +
    "<style>body{font-family:Arial,sans-serif;margin:40px;}" +
    "table{width:100%;border-collapse:collapse;}" +
    "th,td{border:1px solid #ccc;padding:8px;text-align:left;}" +
    "th{background:#f4f4f4;}</style></head><body>" +
    "<h1>Invoice</h1>" +
    "<p><strong>Customer:</strong> " + customerName + "</p>" +
    "<p><strong>Invoice #:</strong> " + invoiceNumber + "</p>" +
    "<table><tr><th>Description</th><th>Amount</th></tr>" +
    "<tr><td>Professional Services</td><td>" + totalAmount + "</td></tr>" +
    "</table>" +
    "<p><strong>Due Date:</strong> " + dueDate + "</p>" +
    "</body></html>";

PdfDocument pdf = PdfDocument.renderHtmlAsPdf(html);
pdf.saveAs(invoiceNumber + ".pdf");
JAVA

For larger projects, consider a Java templating library such as Thymeleaf or Freemarker to manage HTML templates as separate files, inject data via a context object, and keep the template syntax cleaner than string concatenation. Both libraries produce a plain HTML string that passes directly to renderHtmlAsPdf.

TipsWhen generating PDFs in a batch job — for example, one invoice per customer — instantiate ChromePdfRenderOptions once before the loop and reuse the same instance for every render call. Creating a new options object per call adds unnecessary object allocation overhead.


How Do I Extract Text from a PDF in Java?

PdfDocument.extractAllText reads all text content from every page in a PDF and returns it as a single string. This is useful for search indexing, data extraction, and content validation after rendering.

//:path=/static-assets/pdf/content-code-examples/tutorials/html-to-pdf/extract-text.java
import com.ironsoftware.ironpdf.*;
import java.nio.file.Paths;

// Open an existing PDF (or use the result of a render call)
PdfDocument pdf = PdfDocument.fromFile(Paths.get("output.pdf"));

// Extract all text content as a plain string
String text = pdf.extractAllText();
System.out.println(text);
//:path=/static-assets/pdf/content-code-examples/tutorials/html-to-pdf/extract-text.java
import com.ironsoftware.ironpdf.*;
import java.nio.file.Paths;

// Open an existing PDF (or use the result of a render call)
PdfDocument pdf = PdfDocument.fromFile(Paths.get("output.pdf"));

// Extract all text content as a plain string
String text = pdf.extractAllText();
System.out.println(text);
JAVA

The returned string preserves the reading order of text on each page but does not include formatting. Whitespace between columns and table cells is represented as spaces. For PDFs that contain multiple logical sections, extractTextFromPage(int pageIndex) isolates text from a single page, which is more efficient when processing large documents one page at a time.

Text extraction only works on PDFs where text is stored as actual text objects in the PDF structure — PDFs generated by renderHtmlAsPdf always qualify. Scanned documents where pages are images require OCR before text extraction is possible. IronOCR is a complementary Iron Software library that adds OCR capabilities to Java and .NET applications.

For image extraction, use pdf.extractAllImages() which returns a list of BufferedImage objects, one per image found in the document. See the extract text from PDF example and extract images from PDF example for complete code patterns.


How Do I Compress a PDF File?

PdfDocument.compressImages reduces file size by re-encoding embedded images at a lower quality. This is particularly effective for PDFs that were generated from web pages containing large photos or banner images.

//:path=/static-assets/pdf/content-code-examples/tutorials/html-to-pdf/compress-pdf.java
import com.ironsoftware.ironpdf.*;
import java.nio.file.Paths;

PdfDocument pdf = PdfDocument.fromFile(Paths.get("large_report.pdf"));

// Compress embedded images to 60% quality (0–100 scale)
pdf.compressImages(60);

pdf.saveAs("compressed_report.pdf");
//:path=/static-assets/pdf/content-code-examples/tutorials/html-to-pdf/compress-pdf.java
import com.ironsoftware.ironpdf.*;
import java.nio.file.Paths;

PdfDocument pdf = PdfDocument.fromFile(Paths.get("large_report.pdf"));

// Compress embedded images to 60% quality (0–100 scale)
pdf.compressImages(60);

pdf.saveAs("compressed_report.pdf");
JAVA

Quality values between 50 and 75 typically reduce file size by 40–70% with acceptable visual fidelity for screen reading. Values below 40 may introduce visible artifacts on photos, though they can be acceptable for diagrams and screenshots with large solid-color areas.

The overloaded compressImages(int quality, boolean scaleExistingImages) method also accepts a boolean for whether to scale images that are larger than their displayed size in the PDF. Setting this to true further reduces file size by eliminating the excess resolution that occurs when a high-resolution image is embedded but displayed at a much smaller size on the page. This is common in web-to-PDF conversions where images are served at 2x resolution for retina displays.

The PDF compression example demonstrates batch compression across multi-page documents, including how to verify the size reduction after compression.


Next Steps

This tutorial covered the three HTML-to-PDF conversion methods, installation, license configuration, render options, headers and footers, page layout settings, text extraction, and file compression.

To go further, explore these resources in the IronPDF for Java documentation:

  1. PDF generation settingsConfigure DPI, zoom, timeout, and CSS media type for precise rendering control.
  2. Headers and footersAdd HTML headers and footers with brand logos and custom layouts.
  3. Page layout — Set custom margins and paper dimensions for print-ready output.
  4. Watermarks — Apply background and foreground watermarks for document security.
  5. Content extractionExtract text from PDFs and extract images for downstream processing.
  6. File compressionReduce PDF file size for storage and email delivery.
  7. API Reference — Browse the full IronPDF Java API reference for every class and method.

Start a free trial to begin converting HTML to PDF in your Java application today. When you're ready to deploy, view licensing options to find the plan that fits your project.

Frequently Asked Questions

How do I convert an HTML string to PDF in Java?

Call PdfDocument.renderHtmlAsPdf with your HTML string. Pass an optional base path as the second argument so that relative CSS, image, and script references resolve correctly. Call saveAs on the returned PdfDocument to write the file.

How do I convert a URL to PDF in Java?

Call PdfDocument.renderUrlAsPdf with the fully qualified URL. IronPDF fetches the page, waits for JavaScript to execute, and renders the fully loaded DOM to PDF.

How do I convert a local HTML file to PDF in Java?

Call PdfDocument.renderHtmlFileAsPdf with an absolute file path. All relative asset references in the HTML file resolve relative to that file's directory automatically.

How do I install IronPDF in a Java project using Maven?

Add the IronPDF dependency to pom.xml with groupId com.ironsoftware and artifactId ironpdf, then run mvn install from the project root.

How do I remove the watermark from PDFs generated by IronPDF?

Call License.setLicenseKey with a valid license key before any rendering call. Without a license key, IronPDF stamps a tiled watermark on every page.

How do I add headers and footers to a PDF in Java?

Create a TextHeaderFooter instance, set its text properties using format tokens such as {page} and {total-pages}, then call pdf.addTextHeaders and pdf.addTextFooters. For styled headers with logos, use HtmlHeaderFooter instead.

How do I set PDF page margins and paper size in Java?

Create a ChromePdfRenderOptions instance and call setMarginTop, setMarginBottom, setMarginLeft, setMarginRight (in millimeters) and setPaperSize with a PaperSize enum value. Pass the options to any render method.

How do I merge multiple PDFs into one in Java?

Create a List<PdfDocument> with the documents in the desired order and pass it to PdfDocument.merge. The method returns a new PdfDocument containing all pages from all sources.

How do I password-protect a PDF in Java?

Create a SecurityOptions instance, call setUserPassword and setOwnerPassword, then apply it via PdfSecurityManager before saving the document.

How do I extract text from a PDF in Java?

Call pdf.extractAllText() to retrieve all text content as a single string. Use extractTextFromPage(int pageIndex) to extract text from a specific page.

Darrius Serrant
Full Stack Software Engineer (WebOps)

Darrius Serrant holds a Bachelor’s degree in Computer Science from the University of Miami and works as a Full Stack WebOps Marketing Engineer at Iron Software. Drawn to coding from a young age, he saw computing as both mysterious and accessible, making it the perfect medium for creativity ...

Read More
Ready to Get Started?
Version: 2026.4 just released
Still Scrolling Icon

Still Scrolling?

Want proof fast?
run a sample watch your HTML become a PDF.