Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Quick Start

This guide will have you converting HTML to PDF in under 5 minutes.

Basic Conversion

From HTML String

The simplest way to create a PDF is from an HTML string:

{{#tabs }} {{#tab name=“CLI” }}

echo "<h1>Hello, World!</h1>" | printwell convert - -o hello.pdf

{{#endtab }} {{#tab name=“Rust” }}

use printwell::{Converter, PdfOptions};

fn main() -> printwell::Result<()> {
    let converter = Converter::new()?;

    let html = r#"
        <!DOCTYPE html>
        <html>
        <head>
            <style>
                body { font-family: Arial, sans-serif; padding: 40px; }
                h1 { color: #333; }
            </style>
        </head>
        <body>
            <h1>Hello, World!</h1>
            <p>This PDF was generated with printwell.</p>
        </body>
        </html>
    "#;

    let result = converter.html_to_pdf(html, None, None)?;
    result.write_to_file("hello.pdf")?;

    println!("Created hello.pdf ({} pages)", result.page_count);
    Ok(())
}

{{#endtab }} {{#tab name=“Node.js” }}

import { Converter } from 'printwell';

const converter = new Converter();

const html = `
<!DOCTYPE html>
<html>
<head>
    <style>
        body { font-family: Arial, sans-serif; padding: 40px; }
        h1 { color: #333; }
    </style>
</head>
<body>
    <h1>Hello, World!</h1>
    <p>This PDF was generated with printwell.</p>
</body>
</html>
`;

const result = await converter.htmlToPdf(html);
await result.writeToFile('hello.pdf');

console.log(`Created hello.pdf (${result.pageCount} pages)`);

{{#endtab }} {{#tab name=“Python” }}

from printwell import Converter

converter = Converter()

html = """
<!DOCTYPE html>
<html>
<head>
    <style>
        body { font-family: Arial, sans-serif; padding: 40px; }
        h1 { color: #333; }
    </style>
</head>
<body>
    <h1>Hello, World!</h1>
    <p>This PDF was generated with printwell.</p>
</body>
</html>
"""

result = converter.html_to_pdf(html)
result.write_to_file("hello.pdf")

print(f"Created hello.pdf ({result.page_count} pages)")

{{#endtab }} {{#endtabs }}

From URL

Convert any webpage to PDF:

{{#tabs }} {{#tab name=“CLI” }}

printwell convert https://example.com -o example.pdf

{{#endtab }} {{#tab name=“Rust” }}

#![allow(unused)]
fn main() {
let result = converter.url_to_pdf("https://example.com", None, None)?;
result.write_to_file("example.pdf")?;
}

{{#endtab }} {{#tab name=“Node.js” }}

const result = await converter.urlToPdf('https://example.com');
await result.writeToFile('example.pdf');

{{#endtab }} {{#tab name=“Python” }}

result = converter.url_to_pdf("https://example.com")
result.write_to_file("example.pdf")

{{#endtab }} {{#endtabs }}

From File

Convert a local HTML file:

{{#tabs }} {{#tab name=“CLI” }}

printwell convert report.html -o report.pdf

{{#endtab }} {{#tab name=“Rust” }}

#![allow(unused)]
fn main() {
let html = std::fs::read_to_string("report.html")?;
let result = converter.html_to_pdf(&html, None, None)?;
result.write_to_file("report.pdf")?;
}

{{#endtab }} {{#tab name=“Node.js” }}

import { readFile } from 'fs/promises';

const html = await readFile('report.html', 'utf-8');
const result = await converter.htmlToPdf(html);
await result.writeToFile('report.pdf');

{{#endtab }} {{#tab name=“Python” }}

with open("report.html") as f:
    html = f.read()

result = converter.html_to_pdf(html)
result.write_to_file("report.pdf")

{{#endtab }} {{#endtabs }}

Customizing Output

Page Size and Margins

{{#tabs }} {{#tab name=“CLI” }}

printwell convert input.html -o output.pdf \
    --page-size A4 \
    --orientation landscape \
    --margin-top 20 \
    --margin-bottom 20

{{#endtab }} {{#tab name=“Rust” }}

#![allow(unused)]
fn main() {
use printwell::{PdfOptions, PageSize, Orientation, Margins};

let options = PdfOptions::builder()
    .page_size(PageSize::A4)
    .orientation(Orientation::Landscape)
    .margins(Margins::new(20.0, 10.0, 20.0, 10.0))
    .build();

let result = converter.html_to_pdf(html, None, Some(options))?;
}

{{#endtab }} {{#tab name=“Node.js” }}

const result = await converter.htmlToPdf(html, null, {
    pageSize: 'A4',
    orientation: 'Landscape',
    margins: { top: 20, right: 10, bottom: 20, left: 10 }
});

{{#endtab }} {{#tab name=“Python” }}

from printwell import PdfOptions, PageSize, Orientation, Margins

options = PdfOptions(
    page_size=PageSize.A4,
    orientation=Orientation.Landscape,
    margins=Margins(top=20, right=10, bottom=20, left=10)
)

result = converter.html_to_pdf(html, pdf_options=options)

{{#endtab }} {{#endtabs }}

Headers and Footers

{{#tabs }} {{#tab name=“CLI” }}

printwell convert input.html -o output.pdf \
    --header-template '<div style="font-size:10px;text-align:center;width:100%">My Document</div>' \
    --footer-template '<div style="font-size:10px;text-align:center;width:100%">Page <span class="pageNumber"></span> of <span class="totalPages"></span></div>'

{{#endtab }} {{#tab name=“Rust” }}

#![allow(unused)]
fn main() {
let options = PdfOptions::builder()
    .header_template("<div style=\"font-size:10px;text-align:center;width:100%\">My Document</div>")
    .footer_template("<div style=\"font-size:10px;text-align:center;width:100%\">Page <span class=\"pageNumber\"></span> of <span class=\"totalPages\"></span></div>")
    .build();
}

{{#endtab }} {{#tab name=“Node.js” }}

const result = await converter.htmlToPdf(html, null, {
    headerTemplate: '<div style="font-size:10px;text-align:center;width:100%">My Document</div>',
    footerTemplate: '<div style="font-size:10px;text-align:center;width:100%">Page <span class="pageNumber"></span> of <span class="totalPages"></span></div>'
});

{{#endtab }} {{#tab name=“Python” }}

options = PdfOptions(
    header_template='<div style="font-size:10px;text-align:center;width:100%">My Document</div>',
    footer_template='<div style="font-size:10px;text-align:center;width:100%">Page <span class="pageNumber"></span> of <span class="totalPages"></span></div>'
)

{{#endtab }} {{#endtabs }}

Adding Post-Processing

Watermark

{{#tabs }} {{#tab name=“CLI” }}

printwell watermark document.pdf -o watermarked.pdf \
    --text "CONFIDENTIAL" \
    --opacity 0.3 \
    --rotation 45

{{#endtab }} {{#tab name=“Rust” }}

#![allow(unused)]
fn main() {
use printwell::watermark::{Watermark, add_watermark};

let pdf_data = std::fs::read("document.pdf")?;
let watermark = Watermark::text("CONFIDENTIAL")
    .opacity(0.3)
    .rotation(45.0);

let result = add_watermark(&pdf_data, &watermark)?;
std::fs::write("watermarked.pdf", result)?;
}

{{#endtab }} {{#tab name=“Node.js” }}

import { addWatermark } from 'printwell';

const pdfData = await readFile('document.pdf');
const result = addWatermark(pdfData, {
    text: 'CONFIDENTIAL',
    opacity: 0.3,
    rotation: 45
});
await writeFile('watermarked.pdf', result);

{{#endtab }} {{#tab name=“Python” }}

from printwell import add_watermark, Watermark

with open("document.pdf", "rb") as f:
    pdf_data = f.read()

watermark = Watermark.text_watermark(
    text="CONFIDENTIAL",
    opacity=0.3,
    rotation=45
)
result = add_watermark(pdf_data, watermark)

with open("watermarked.pdf", "wb") as f:
    f.write(result)

{{#endtab }} {{#endtabs }}

Password Protection

{{#tabs }} {{#tab name=“CLI” }}

printwell encrypt document.pdf -o encrypted.pdf \
    --owner-password admin123 \
    --user-password user123 \
    --no-print --no-copy

{{#endtab }} {{#tab name=“Rust” }}

#![allow(unused)]
fn main() {
use printwell::encrypt::{encrypt_pdf, EncryptionOptions, Permissions};

let options = EncryptionOptions::builder()
    .owner_password("admin123")
    .user_password("user123")
    .permissions(Permissions::none().allow_screen_readers())
    .build();

let result = encrypt_pdf(&pdf_data, &options)?;
}

{{#endtab }} {{#tab name=“Node.js” }}

import { encryptPdf } from 'printwell';

const result = encryptPdf(pdfData, {
    ownerPassword: 'admin123',
    userPassword: 'user123',
    permissions: { print: false, copy: false }
});

{{#endtab }} {{#tab name=“Python” }}

from printwell import encrypt_pdf, EncryptionOptions, Permissions

options = EncryptionOptions(
    owner_password="admin123",
    user_password="user123",
    permissions=Permissions(print=False, copy=False)
)
result = encrypt_pdf(pdf_data, options)

{{#endtab }} {{#endtabs }}

Next Steps