PDFluent connects to a headless browser via its browser bridge to render HTML to PDF. This gives you accurate CSS rendering, web fonts, and SVG support.
use pdfluent::HtmlToPdf;
fn main() -> pdfluent::Result<()> {
let html = r#"
<!DOCTYPE html>
<html>
<head>
<style>
body { font-family: sans-serif; padding: 40px; }
h1 { color: #1a1a1a; }
.total { font-weight: bold; color: #2563eb; }
</style>
</head>
<body>
<h1>Invoice #INV-2024-042</h1>
<p>Due: 2024-05-01</p>
<p class="total">Total: EUR 1,200.00</p>
</body>
</html>
"#;
let pdf_bytes = HtmlToPdf::new()
.page_size_a4()
.margin_mm(20.0)
.render_html(html)?;
std::fs::write("invoice.pdf", &pdf_bytes)?;
println!("Saved invoice.pdf ({} bytes)", pdf_bytes.len());
Ok(())
}The html feature requires a Chromium or Chrome installation on the machine. PDFluent calls it via the Chrome DevTools Protocol (CDP). Install the browser bridge with the provided CLI helper.
# Cargo.toml
[dependencies]
pdfluent = { version = "0.9", features = ["html"] }
# Install Chromium for the bridge (Linux)
apt-get install -y chromium-browser
# macOS
brew install --cask chromium
# Or set a custom Chrome path via environment variable
# PDFLUENT_CHROME_PATH=/usr/bin/google-chromeHtmlToPdf::new() launches a headless browser, loads the HTML, and triggers the browser print-to-PDF function. The bytes are returned in memory.
use pdfluent::HtmlToPdf;
let html = "<h1>Hello, PDF</h1><p>This is a test.</p>";
let pdf_bytes = HtmlToPdf::new()
.page_size_a4()
.margin_mm(15.0)
.render_html(html)?;
std::fs::write("output.pdf", &pdf_bytes)?;render_url() navigates to a URL and waits for the page to fully load before printing. Useful for reports served from a local web server.
let pdf_bytes = HtmlToPdf::new()
.page_size_a4()
.wait_for_idle_ms(1000) // wait 1 s for JS to finish
.render_url("http://localhost:3000/invoice/42")?;
std::fs::write("invoice-42.pdf", &pdf_bytes)?;Pass a file:// URL or use render_file(). All relative paths (images, CSS) must be resolvable from the file location.
let pdf_bytes = HtmlToPdf::new()
.page_size_a4()
.render_file("/tmp/invoice.html")?;
std::fs::write("invoice.pdf", &pdf_bytes)?;Control page size, margins, header/footer, and background printing.
use pdfluent::{HtmlToPdf, PageSize};
let pdf_bytes = HtmlToPdf::new()
.page_size(PageSize::Letter)
.margin_top_mm(15.0)
.margin_bottom_mm(15.0)
.margin_left_mm(20.0)
.margin_right_mm(20.0)
.print_background(true)
.header_template("<div style='font-size:10px'>Report</div>")
.footer_template("<div style='font-size:10px'>Page <span class='pageNumber'></span></div>")
.render_html(&html)?;No JVM, no runtime, no DLL dependencies. Ships as a single native binary or WASM module.
Rust's ownership model prevents buffer overflows and use-after-free. No segfaults in PDF parsing.
Same code runs server-side, in Docker, on AWS Lambda, on Cloudflare Workers, or in the browser via WASM.