Skip to main content

Command Palette

Search for a command to run...

AOP Direct Print?

Published
4 min readView as Markdown
T

Databaseguy, Oracle Apex Lover

Direct Printing in Oracle APEX: From Kiosk Mode to IPP Printing

The Challenge

In our ERP System, I faced a typical challenge: We needed a solution for direct, automatic printing of PDFs on forklift terminals – without requiring users to manually confirm the print dialog every time.

The existing solution with sxaop.preparePdfDisplay() worked well for PDF preview, but for our warehouse employees, it was impractical to confirm the print dialog for every picking slip.

Approach 1: JavaScript Direct Print with Kiosk Mode

Initially, we developed a JavaScript solution that enables direct printing alongside the existing PDF preview:

The JavaScript Implementation

// For PDF preview (as before)
sxaop.preparePdfDisplay('R4093_Action','PRINT',100,10000);

// NEW: For direct print without dialog
sxaop.preparePdfPrint('R4093_Action','PRINT',100,10000);

The preparePdfPrint function only shows the user a "Printing..." message while the PDF is automatically sent to the printer in the background.

The Catch: Kiosk Mode Required

Browsers block automatic printing without user interaction for security reasons. The solution? Microsoft Edge in Kiosk mode with the --kiosk-printing option:

"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe" ^
  --kiosk https://theapp.dev.at/ords/pdb01/r/erp/erpstapler/login ^
  --kiosk-printing ^
  --edge-kiosk-type=public-browsing

Advantages of this solution:

  • ✅ Works reliably in Edge/Chrome

  • ✅ No additional server infrastructure required

  • ✅ Simple JavaScript integration

Disadvantages:

  • ❌ Kiosk mode required on every terminal

  • ❌ Browser must be started with special parameters

  • ❌ Difficult to maintain with many terminals

  • ❌ No central printer configuration possible

Approach 2: AOP IPP Printing (Our Final Solution)

After thorough evaluation, we decided on AOP IPP (Internet Printing Protocol) functionality. This solution prints directly from the Oracle server to the network printer – completely without browser involvement.

The PL/SQL Implementation

BEGIN
    -- Configure optional watermark
    zodis_aop.aop_api24_pkg.g_output_watermark := 
        p_adm.get_param('pdf_watermark_text','');
    zodis_aop.aop_api24_pkg.g_output_watermark_color := 'red';
    zodis_aop.aop_api24_pkg.g_output_watermark_font := 'Arial';
    zodis_aop.aop_api24_pkg.g_output_watermark_opacity := 50;
    zodis_aop.aop_api24_pkg.g_output_watermark_size := 45;

    -- IPP Printer Configuration
    zodis_aop.aop_api_pkg.g_ip_printer_location := 
        p_adm.get_param('edv_ipp_printer','');  
        -- e.g. 'ipp://192.168.1.100:631/printers/Warehouse_Printer'
    zodis_aop.aop_api_pkg.g_ip_printer_version := '2.0';
    zodis_aop.aop_api_pkg.g_ip_printer_requester := 'ZODIS';
    zodis_aop.aop_api_pkg.g_ip_printer_job_name := 'Picking_Slip';
    zodis_aop.aop_api_pkg.g_ip_printer_return_output := 'true';
END;

How It Works

  1. PDF Generation happens as usual via AOP

  2. Instead of browser download, the Oracle server sends the PDF directly via IPP to the printer

  3. Printer status is optionally reported back

  4. No browser involvement required anymore

Printer Configuration

Printer URLs are centrally managed in our parameter table:

-- Each branch/terminal can have its own printer configured
INSERT INTO adm_parameter (param_name, param_value, param_description)
VALUES ('edv_ipp_printer', 
        'ipp://warehouse-printer-01.zgonc.local:631/printers/Zebra_ZT411',
        'IPP Printer for Warehouse Terminal 01');

Why IPP is the Better Solution

Advantages of the IPP Solution:

No Browser Dependencies

  • Works with any browser

  • No kiosk mode needed

  • No special startup parameters

Central Management

  • Printer configuration in the database

  • Easy changing of printers per terminal

  • Watermarks centrally controllable

Better Control

  • Print jobs are logged

  • Status feedback possible

  • Error handling server-side

More Robust

  • Independent of browser updates

  • No JavaScript restrictions

  • Works even if browser crashes

More Flexible

  • Different printers per user/location

  • Dynamic printer selection based on context

  • Easy integration into existing workflows

Setting Up IPP Printers

Most modern network printers support IPP out-of-the-box. Here's an example for common printers:

Zebra Label Printer:

ipp://192.168.1.100:631/printers/ZebraZT411

HP Network Printer:

ipp://192.168.1.101/ipp/print

CUPS (Linux):

ipp://printserver.domain.local:631/printers/warehouse_01

Migration from JavaScript to IPP Approach

The migration was surprisingly simple:

Before (JavaScript with Kiosk Mode):

// In APEX Dynamic Action
sxaop.preparePdfPrint('R4093_Action','PRINT',100,10000);

After (IPP Printing):

-- In PL/SQL before AOP call
BEGIN
    zodis_aop.aop_api_pkg.g_ip_printer_location := 
        get_user_printer(); -- Determines printer for current user

    -- Then normal AOP call
    aop_api24_pkg.plsql_call_to_aop(...);
END;

The browser no longer receives a file – the PDF is printed directly!

Best Practices & Learnings

1. Check Printer Availability

FUNCTION is_printer_available(p_printer_url VARCHAR2) RETURN BOOLEAN IS
    l_response CLOB;
BEGIN
    -- Send test request to printer
    l_response := apex_web_service.make_rest_request(
        p_url => p_printer_url,
        p_http_method => 'GET'
    );
    RETURN apex_web_service.g_status_code = 200;
EXCEPTION
    WHEN OTHERS THEN
        RETURN FALSE;
END;

2. Fallback Strategy

BEGIN
    IF is_printer_available(l_primary_printer) THEN
        zodis_aop.aop_api_pkg.g_ip_printer_location := l_primary_printer;
    ELSE
        -- Fallback to backup printer
        zodis_aop.aop_api_pkg.g_ip_printer_location := l_backup_printer;
        log_warning('Primary printer unavailable, using backup');
    END IF;
END;

3. User-Specific Printers

FUNCTION get_user_printer RETURN VARCHAR2 IS
    l_printer VARCHAR2(500);
BEGIN
    -- Determine printer based on user location
    SELECT printer_url INTO l_printer
    FROM user_printer_mapping
    WHERE username = :APP_USER
    AND location_id = get_user_location();

    RETURN l_printer;
EXCEPTION
    WHEN NO_DATA_FOUND THEN
        RETURN get_default_printer();
END;

Conclusion

While the JavaScript solution with Kiosk mode works technically, the AOP IPP Printing solution offers significantly more advantages for production use:

  • Easier maintenance

  • Better scalability

  • Higher reliability

  • Central management

For warehouse management systems with dedicated terminals, IPP Printing is definitely the way to go. The initial setup is somewhat more complex, but pays off in the long run through significantly lower maintenance effort.