generate_pdf_from_html

Function generate_pdf_from_html 

Source
pub fn generate_pdf_from_html(
    pool: &Mutex<BrowserPool>,
    request: &PdfFromHtmlRequest,
) -> Result<PdfResponse, PdfServiceError>
Expand description

Generate a PDF from HTML content.

Loads the provided HTML content into a browser tab using a data URL, waits for any JavaScript execution, and generates a PDF.

§Thread Safety

This function is thread-safe and can be called concurrently from multiple threads. See generate_pdf_from_url for details.

§Blocking Behavior

This function blocks the calling thread. See generate_pdf_from_url for guidance on async usage.

§How It Works

The HTML content is converted to a data URL:

data:text/html;charset=utf-8,<encoded-html-content>

This allows loading HTML directly without a web server. The browser renders the HTML as if it were loaded from a regular URL.

§Arguments

  • pool - Reference to the mutex-wrapped browser pool
  • request - HTML content and generation parameters. See PdfFromHtmlRequest.

§Returns

  • Ok(PdfResponse) - Successfully generated PDF
  • Err(PdfServiceError) - Error details

§Errors

ErrorCauseResolution
EmptyHtmlHTML content is empty/whitespaceProvide HTML content
PoolLockFailedMutex poisonedRestart service
BrowserUnavailablePool exhaustedRetry or increase pool size
NavigationFailedHTML parsing issueCheck HTML validity
PdfGenerationFailedRendering issueSimplify HTML

§Limitations

§External Resources

Since HTML is loaded via data URL, relative URLs don’t work:

<!-- ❌ Won't work - relative URL -->
<img src="/images/logo.png">

<!-- ✅ Works - absolute URL -->
<img src="https://example.com/images/logo.png">

<!-- ✅ Works - inline base64 -->
<img src="data:image/png;base64,iVBORw0KGgo...">

§Size Limits

Data URLs have browser-specific size limits. For very large HTML documents (> 1MB), consider:

  • Hosting the HTML on a temporary server
  • Using generate_pdf_from_url instead
  • Splitting into multiple PDFs

§Examples

§Simple HTML

use html2pdf_api::service::{generate_pdf_from_html, PdfFromHtmlRequest};

let request = PdfFromHtmlRequest {
    html: "<h1>Hello World</h1><p>This is a test.</p>".to_string(),
    ..Default::default()
};

let response = generate_pdf_from_html(&pool, &request)?;
std::fs::write("output.pdf", &response.data)?;

§Complete Document with Styling

let html = r#"
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <style>
        body {
            font-family: 'Arial', sans-serif;
            margin: 40px;
            color: #333;
        }
        h1 {
            color: #0066cc;
            border-bottom: 2px solid #0066cc;
            padding-bottom: 10px;
        }
        table {
            width: 100%;
            border-collapse: collapse;
            margin-top: 20px;
        }
        th, td {
            border: 1px solid #ddd;
            padding: 12px;
            text-align: left;
        }
        th {
            background-color: #f5f5f5;
        }
    </style>
</head>
<body>
    <h1>Monthly Report</h1>
    <p>Generated on: 2024-01-15</p>
    <table>
        <tr><th>Metric</th><th>Value</th></tr>
        <tr><td>Revenue</td><td>$50,000</td></tr>
        <tr><td>Users</td><td>1,234</td></tr>
    </table>
</body>
</html>
"#;

let request = PdfFromHtmlRequest {
    html: html.to_string(),
    filename: Some("monthly-report.pdf".to_string()),
    print_background: Some(true), // Include styled backgrounds
    ..Default::default()
};

let response = generate_pdf_from_html(&pool, &request)?;

§With Embedded Images

// Base64 encode an image
let image_base64 = base64::encode(std::fs::read("logo.png")?);

let html = format!(r#"
<!DOCTYPE html>
<html>
<body>
    <img src="data:image/png;base64,{}" alt="Logo">
    <h1>Company Report</h1>
</body>
</html>
"#, image_base64);

let request = PdfFromHtmlRequest {
    html,
    ..Default::default()
};

let response = generate_pdf_from_html(&pool, &request)?;