HTML to PDF Generation in Power Automate

Generate professional PDFs from HTML templates directly in your Microsoft Power Automate flows. Perfect for invoices, receipts, reports, certificates, and any document that requires custom styling and layouts.

📖 Want a complete step-by-step guide? Check out our Power Automate PDF Generation Tutorial with screenshots, QR code examples, and best practices.

Quick Start Guide

Step 1: Get Your API Key

  1. Visit customjs.space and click Sign in
  2. Complete registration by either providing your email and password or using your Google account
  3. Once registered, you will be redirected to the CustomJS app dashboard
  4. Click Show under API Key to reveal your API key
  5. Copy your API key for the next step
CustomJS API Key Dashboard
CustomJS API Key Dashboard

Step 2: Create Connection in Power Automate

  1. Open your Power Automate flow
  2. Add a new action and search for "CustomJS"
  3. Select "HTML to PDF" action
  4. When prompted, create a new connection:
    • Connection Name: CustomJS (or any name you prefer)
    • API Key: Paste your API key from Step 1
  5. Click Create
Create CustomJS Connection in Power Automate
Create CustomJS Connection in Power Automate

Step 3: Find the HTML to PDF Module

  1. In your Power Automate flow, click + New step
  2. Search for "CustomJS"
  3. Select the "HTML to PDF" action from the list
Find CustomJS HTML to PDF Module
Find CustomJS HTML to PDF Module

Step 4: Add Your HTML Code

  1. In the HTML Content field, paste your HTML template
  2. You can use static HTML or insert dynamic content from previous steps
  3. The action returns a base64-encoded PDF ready for email or storage
Add HTML Code to CustomJS Action
Add HTML Code to CustomJS Action

What you get:

  • ✅ 600 free PDFs per month
  • ✅ Full HTML5, CSS3, and JavaScript support
  • ✅ QR codes, barcodes, and custom fonts
  • ✅ No Azure Functions or complex setup needed

HTML Input

The action accepts complete HTML documents with embedded CSS and JavaScript. You can:

  • Use inline CSS for styling (recommended for PDFs)
  • Include custom fonts via @font-face or web fonts
  • Add QR codes, barcodes, charts using JavaScript libraries
  • Use dynamic content from Power Automate variables

Example: Simple Invoice

<!DOCTYPE html>
<html>
<head>
  <style>
    body { font-family: Arial, sans-serif; padding: 40px; }
    .header { text-align: center; margin-bottom: 30px; }
    .invoice-details { margin: 20px 0; }
    table { width: 100%; border-collapse: collapse; }
    th, td { padding: 10px; text-align: left; border-bottom: 1px solid #ddd; }
  </style>
</head>
<body>
  <div class="header">
    <h1>INVOICE</h1>
    <p>Invoice #12345</p>
  </div>
  
  <div class="invoice-details">
    <p><strong>Bill To:</strong> John Doe</p>
    <p><strong>Date:</strong> 2025-01-14</p>
  </div>
  
  <table>
    <thead>
      <tr>
        <th>Item</th>
        <th>Quantity</th>
        <th>Price</th>
        <th>Total</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>Web Development</td>
        <td>10 hours</td>
        <td>$100</td>
        <td>$1,000</td>
      </tr>
    </tbody>
  </table>
  
  <div style="text-align: right; margin-top: 30px;">
    <h2>Total: $1,000</h2>
  </div>
</body>
</html>

Using Dynamic Content

The best practice is to use a Data Operation - Compose action to map your trigger data to clean field names, then reference those fields in your HTML template.

Advanced PDF Features

📦 Using External JavaScript Libraries (QR Codes)

You can use external JavaScript libraries like QRCode.js in your PDF templates. When using ES Modules, wrap your import in a module script tag:

<script type="module">
  import QRCode from 'https://cdn.jsdelivr.net/npm/qrcode@1.5.4/+esm';
  
  // Generate QR code
  const qrDataUrl = await QRCode.toDataURL('https://example.com', {
    width: 150,
    margin: 1
  });
  
  // Set the image source
  document.getElementById('qr').src = qrDataUrl;
</script>

<img id="qr" alt="QR Code" />

→ Read the complete QR Code guide

⏱️ Async Rendering with window.__RENDER_DONE__

When using asynchronous JavaScript (QR codes, charts, API calls), you must signal when your content is ready by setting window.__RENDER_DONE__ = true. The PDF generator waits for this flag before capturing the page.

<script type="module">
  import QRCode from 'https://cdn.jsdelivr.net/npm/qrcode@1.5.4/+esm';
  
  // Initialize as false
  window.__RENDER_DONE__ = false;
  
  async function generateQR() {
    // Your async operations
    const qrDataUrl = await QRCode.toDataURL('https://example.com');
    document.getElementById('qr').src = qrDataUrl;
    
    // Signal that rendering is complete
    window.__RENDER_DONE__ = true;
  }
  
  // Start generation
  if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', generateQR);
  } else {
    generateQR();
  }
</script>

⚠️ Important: Without setting window.__RENDER_DONE__ = true, your PDF may be blank or incomplete because the generator won't wait for async operations to finish!