Skip to main content

Command Palette

Search for a command to run...

Methods to Convert HTML to PDF in Oracle APEX

Updated
•4 min read

Converting HTML content to PDF is a common requirement in web applications. This blog post demonstrates three different approaches to achieve this in Oracle APEX applications, each with its own advantages and use cases.

🔗 Live Demo

Overview of Methods

  • Method 1: jsPDF with Fixed Dimensions - Simple, predictable PDF generation with predefined page sizes
  • Method 2: jsPDF with Dynamic Scaling - Intelligent content adaptation with automatic orientation and scaling
  • Method 3: Browser Print Method - Leverages browser's native PDF generation capabilities

Database Setup

First, create the table to store HTML documents. For the complete DDL script, see html_tmp_table.sql.

Required Libraries

Add these libraries to your APEX page (Page > JavaScript > File URLs):

https://github.com/Aftorres02/blog_app_examples/tree/master/post_2025/18_tmp_html_to_pdf_dow/libs

Library References:

APEX Process

Create an AJAX process named GET_HTML_CONTENT:

declare
    l_html_content clob;
    l_document_id number;
begin
    l_document_id := apex_application.g_x01;

    select html_content, document_name
    into l_html_content, :P1210_DOCUMENT_NAME
    from html_documents
    where id = l_document_id
    and active_yn = 'Y';

    apex_json.open_object;
    apex_json.write('html_content', l_html_content);
    apex_json.write('document_name', :P1210_DOCUMENT_NAME);
    apex_json.close_object;

exception
    when no_data_found then
        apex_json.open_object;
        apex_json.write('error', 'Document not found');
        apex_json.close_object;
end;

Method 1: jsPDF with Fixed Dimensions

What it does: Creates a PDF with predefined dimensions (900x630 points) and converts HTML content directly to PDF format. This method provides good control over page size but may not automatically adjust to content dimensions.

apex.server.process(
  "GET_HTML_CONTENT",
  {
    x01: apex.item("P1210_DOCUMENT_ID").getValue(),
  },
  {
    success: function (data) {
      var doc = new jspdf.jsPDF("p", "pt", [900, 630]);

      doc.html(data.html_content, {
        callback: function (doc) {
          if (doc.getNumberOfPages() >= 2) {
            doc.deletePage(2);
          }
          var filename = data.document_name;
          doc.save(filename + ".pdf");
        },

        // Set the rendering starting point and size
        x: 0,
        y: 0,
        margin: 20,
        width: 590, // FULL width of the page in points
        windowWidth: 590, // Optional: helps html2canvas understand layout

        html2canvas: {
          useCORS: true,
          allowTaint: true,
          scale: 1, // Adjust this for quality vs performance
        },
      });
    },
    error: function () {
      alert("Error loading document content");
    },
  }
);

Method 2: jsPDF with Dynamic Orientation and Scaling

What it does: Automatically detects content dimensions and chooses the best orientation (portrait/landscape) and scaling factor to fit the content perfectly within the PDF page. This method provides the most intelligent content adaptation.

apex.server.process(
  "GET_HTML_CONTENT",
  {
    x01: apex.item("P1210_DOCUMENT_ID").getValue(),
  },
  {
    success: function (data) {
      // Create a hidden container dynamically
      let tempContainer = document.createElement("div");
      tempContainer.id = "htmlContentHidden";
      document.body.appendChild(tempContainer);

      // Insert HTML content
      tempContainer.innerHTML = data.html_content;

      // Measure content dimensions
      const contentWidth = tempContainer.scrollWidth;
      const contentHeight = tempContainer.scrollHeight;

      // Decide orientation based on aspect ratio
      let orientation = contentWidth > contentHeight ? "l" : "p";

      // Init jsPDF with dynamic orientation
      const { jsPDF } = window.jspdf;
      let doc = new jsPDF(orientation, "pt", "a4");

      // Get actual page dimensions from jsPDF
      const pageWidth = doc.internal.pageSize.getWidth();
      const pageHeight = doc.internal.pageSize.getHeight();

      // Calculate scale so content fits into page width (max = 1)
      const scaleFactor = Math.min((pageWidth - 40) / contentWidth, 1);

      // Generate PDF
      doc.html(tempContainer, {
        callback: function (doc) {
          doc.save("dynamic_fit.pdf");
          // Clean up
          document.body.removeChild(tempContainer);
        },
        x: 20,
        y: 20,
        width: pageWidth - 40, // usable width with margins
        windowWidth: contentWidth, // original HTML width
        html2canvas: {
          scale: scaleFactor,
          useCORS: true,
          allowTaint: true,
        },
      });
    },
    error: function () {
      alert("Error loading document content");
    },
  }
);

Method 3: Browser Print Method

What it does: Opens the HTML content in a new browser window and triggers the browser's native print dialog, allowing users to save as PDF using their browser's built-in PDF functionality. This method leverages the browser's native PDF generation capabilities.

apex.server.process(
  "GET_HTML_CONTENT",
  {
    x01: apex.item("P1210_DOCUMENT_ID").getValue(),
  },
  {
    success: function (data) {
      var printWindow = window.open('', '_blank', 'width=800,height=600');
      printWindow.document.write('<!DOCTYPE html>');
      printWindow.document.write('<html><head><title>Document</title>');
      printWindow.document.write('<style>body{font-family:Arial,sans-serif;margin:20px;}</style>');
      printWindow.document.write('</head><body>');
      printWindow.document.write(data.html_content);
      printWindow.document.write('</body></html>');
      printWindow.document.close();

      setTimeout(function() {
          printWindow.print();
          setTimeout(function() {
              printWindow.close();
          }, 1000);
      }, 500);
    },
    error: function () {
      alert("Error loading document content");
    },
  }
);

Comparison of Methods

MethodProsConsBest For
Method 1: Fixed DimensionsSimple, predictable outputMay not fit all contentStandard documents
Method 2: Dynamic ScalingIntelligent content adaptationMore complex codeVariable content sizes
Method 3: Browser PrintNo external libraries neededRequires user interactionSimple implementations

More from this blog

A little knowledge to share-Oracle APEX

17 posts

Soy Ingeniero de Aplicaciones desde el 2012, he trabajado con Oracle APEX desde el 2017en versiones 5, 18, 20, 21. En los ultimos años he desarrollado habilidades en CSS, JavaScript, Jquery y PlSql , I specialize in Oracle APEX (Oracle Application Express )