APEX An Oracle APEX application for your development workspace

The visual PDF report designer for Oracle APEX

VinAura is an Oracle APEX application that you install in your development environment. In it you draw invoices, statements and labels on a canvas, bind them to your SQL queries and page items, and get the PDF from any APEX page with one PL/SQL call. VinAura runs entirely inside your Oracle database, with nothing to install on a server and no Word templates. It is free to use.

  • Invoices
  • Statements
  • Labels & barcodes
  • Batch PDFs
  • Totals & groups
  • Page X of Y
  • One PL/SQL call
VinAura · Designer
VinAura PDF report designer for Oracle APEX: SQL queries on the left, an invoice layout with bands on the canvas, table properties on the right

What you no longer need for PDFs in APEX

  • BI Publisherand its print server
  • Word / RTF templatesand XML mapping
  • Hand-coded PDFx/y positions in PL/SQL
  • External servicesyour data stays in the database
What VinAura is

Design in development. Print in production.

VinAura is an Oracle APEX application that runs inside Oracle APEX, next to your own applications. You use it in your development environment to design the reports your applications print. Production needs only the small PL/SQL runtime and your reports, not the designer.

Development

The designer application

Import VinAura into your development workspace, beside the application you are building. There you write each report's queries, draw its layout, preview it, and try the call your pages will make.

  • The VinAura APEX application: designer, reports, log, How to Use
  • The PDF_* tables and packages, including the designer package
  • Optional demo data and sample reports to learn from
Production

Only the runtime

Your application in production prints with one PL/SQL call. It needs four tables, three packages and the reports you designed. There is no designer application, no demo, and no extra server.

  • Tables PDF_REPORTS, PDF_QUERIES, PDF_IMAGES, PDF_LOG
  • Packages PDF_API, PDF_ENGINE, PDF_WRITER
  • Your reports and logos, exported from development as JSON or copied as rows
Why VinAura

PDF reports in APEX shouldn't need a second product

An invoice with a logo, a bill-to box, a table of lines, totals and a signature is everyday work. In APEX it usually means BI Publisher and Word templates, or a PDF library where every line is placed by hand. VinAura gives you a designer instead, and keeps the whole thing in PL/SQL.

The usual way

Templates, mappings and a print server

  • Design in Microsoft Word, then map every field to an XML element.
  • Install and license a print server, and keep it running beside the database.
  • Or write a PDF by hand: every text, line and page break at x/y positions in code.
  • A change of layout means a developer, a new template and a new deployment.
With VinAura

A designer, your queries and one call

  • Draw the page in the browser: text and fields, boxes, lines, images, tables, barcodes.
  • Bind it to up to ten SQL queries that use your page items, :P11_INVOICE_ID.
  • pdf_api.generate('INVOICE') returns the PDF as a BLOB, made in the database.
  • Change the layout, press Save: every page that prints it uses the new one at once.
How it works

Three steps from data to PDF

Queries give the data, the designer gives the look, and one procedure makes the PDF wherever you need it.

01

Write the queries

One SELECT for each part of the document: the header, the lines, the totals. Page items are bind variables.

Q2 · invoice lines
select line_no, description, qty, unit_price, amount from invoice_lines where invoice_id = :P11_INVOICE_ID order by line_no
02

Draw the layout

Drag fields onto the page, add a table for the lines with totals, boxes, a logo and page numbers. Preview it at once.

Designer
VinAura designer with the fields of the queries and a selected field
03

Call it from APEX

Get the BLOB to store or e-mail, or send it to the browser in a dialog or a new tab.

PL/SQL
declare l_pdf blob; begin l_pdf := pdf_api.generate('INVOICE'); end;
Inside VinAura

A real designer, in your APEX workspace

VinAura · Designer
VinAura designer: an invoice layout with its table selected and the column properties VinAura designer: the three queries of an invoice with their columns and bind variables VinAura preview of a tax invoice PDF made from the designer VinAura designer: a product label with a barcode VinAura page setup: page size, orientation, width, height and margins An APEX invoice form with lines, totals and Preview Invoice and New tab buttons An APEX modal dialog showing a batch of tax invoices as a PDF

The page in bands: page header, report header, the body with its table, the summary and the page footer. The selected table shows its columns, formats and totals on the right.

Features

Everything an invoice, a statement or a label needs

01Bands that flowPage header and footer on every page, a report header once, a body that grows over pages, a summary at the end or at the foot of the last page.
02Tables over pagesRows grow with long text, the header row repeats on every page, zebra rows and grid lines as you like.
03Totals and groupsSum, count, average, min and max per column; group headings with sub-totals; totals of any query anywhere on the page.
04Fields and formatsMix text and fields: Invoice No. {Q1.INVOICE_NO}, with Oracle format masks for numbers and dates.
05Amount in words{WORDS(Q3.TOTAL)} in lakh and crore with paise, or in million and billion.
06Print whenShow an element only when a condition holds: a PAID stamp when {Q1.STATUS} = PAID.
07Labels and barcodesSheets of labels across and down, Code 128 barcodes, a start position for a sheet that is already partly used.
08Batch documentsOne document per row of a query: all the invoices of a day in one PDF, each with its own page numbers.
09Any page sizeA3 to A6, Letter, Legal, envelopes or a custom size, portrait or landscape, with your margins.
10Logos and imagesUpload a logo, a stamp or a signature once; or print an image from a BLOB column of your query.
11Fonts and shapesHelvetica, Arial, Arial Narrow, Arial Black, Times and Courier; boxes, rounded boxes, circles and dashed lines.
12Export, import and logMove a report from development to production as JSON; every PDF made is logged with its time and size.
Sample PDFs

Real PDFs from the VinAura engine

These come with VinAura as ready-made reports on demo data. Open one, change it in the designer, and see what the engine does with long tables, totals and page breaks.

Tutorial

From install to a PDF in a dialog

Everything below is also in the application, on its How to Use page, and in the demo screens that come with it. The names are those of the demo: an invoice form on page 11 with the item P11_INVOICE_ID.

Chapter 1 · Install

Install it in minutes

VinAura is an APEX application and a set of PL/SQL packages and tables. Install it in a schema of its own, or straight into your application's schema.

You needOracle Database 19c or later with APEX. The designer application is an APEX 26.1 export.

The quick way: import the application

  1. App Builder > Import > dist/pdf_report_designer.sql from the GitHub repository.
  2. Choose the parsing schema, and Install Supporting Objects.
  3. It creates the PDF_* tables and packages, and the demo tables and sample reports.

Into your own application's schema

Run the scripts in this order as your schema, then import the application without its supporting objects. Leave out the demo scripts and the Demo menu hides itself.

SQLcl / SQL Developer
@sql/10_tables.sql @sql/20_pdf_writer.sql @sql/30_pdf_engine.sql @sql/40_pdf_api.sql @sql/45_pdf_designer.sql -- where the designer runs -- optional demo: @sql/50_demo_data.sql @sql/60_samples.sql

Or a schema of its own, shared by several applications

One grant and one synonym for every application schema that prints. The queries of a report always run as the schema that calls the API, so each application reads its own tables.

SQL
grant execute on pdfgen.pdf_api to your_schema; -- then, as your_schema: create synonym pdf_api for pdfgen.pdf_api;
Chapter 2 · Queries

Create a report and write its queries

Reports > New Report. Give it a code, for example INVOICE: your pages call the report by it. Then write one query for each part of the document.

TipUse your page items as bind variables. When the report is printed, they take the values of the page.

Q1: the header, one row

Q1
select i.invoice_no, i.invoice_date, i.due_date, i.status, c.name customer_name, c.address, c.gstin from invoices i join customers c on c.customer_id = i.customer_id where i.invoice_id = :P11_INVOICE_ID

Q2: the lines, many rows

Q2
select l.line_no sno, p.name description, l.qty, l.unit_price, round(l.qty * l.unit_price, 2) amount from invoice_lines l join products p on p.product_id = l.product_id where l.invoice_id = :P11_INVOICE_ID order by l.line_no

Press beside a query to check it: its columns appear under Fields, its bind variables under Parameters, where you give test values for Preview.

Chapter 3 · Layout

Design the layout

The page is divided in bands. Put what repeats on every page in the page header and footer, the bill-to boxes in the report header, the lines table in the body and the totals in the summary.

KeysDel deletes, Ctrl+D duplicates, the arrows move (Shift: 10 pt), Ctrl+Z undoes, Ctrl+S saves.

Fields, text, boxes and images

  • Drag a field from Fields onto a band, or add a Text / Field and type text and fields together: Invoice No. {Q1.INVOICE_NO}.
  • Boxes, rounded boxes, circles and lines frame the page; upload a logo once and use it in every report.
  • Every element has a font, colour, alignment, border and background, and an optional Print when condition.
Designer · Tax Invoice
The invoice layout in the VinAura designer

A table for the lines

Add a Table and choose its query (Q2). Its columns come from the fields; give each a heading, a width, an alignment, a format mask and a total. Drop more fields on the table to add columns.

Tokens you can type in any text

{Q1.CUSTOMER_NAME}a column (the current row in a table or label, else the first row) {Q3.TOTAL|FM999G990D00}with a format mask {SUM(Q2.AMOUNT)}also COUNT, AVG, MIN, MAX over a query {WORDS(Q3.TOTAL)}the amount in words (lakh, crore, paise) Page {PAGE} of {PAGES}page numbers, in the page header or footer {TODAY|DD-MON-YYYY}also {NOW}, {APP_USER}, {REPORT}

Page setup

Page size (A4 by default, A3, A5, Letter, Legal and more, or a custom size), portrait or landscape, margins, and the units the designer shows: millimetres, inches or points.

Chapter 4 · Preview

Preview, save and try the API

Preview makes the real PDF from the layout on the screen, saved or not, with the test values of the Parameters tab. Save stores the layout and the queries; every page that prints the report uses it at once.

The preview

Preview
Preview of the invoice PDF in the designer

Try the API

The Try the API page runs pdf_api.download for any report with the parameters you type, and shows the PL/SQL call to copy into your page.

Try the API
The Try the API page of VinAura
Chapter 5 · BLOB

Get the PDF as a BLOB

pdf_api.generate returns the PDF. Page items are read from session state, or you give the values yourself as name/value pairs.

What the pairs meanapex_t_varchar2('P11_INVOICE_ID', 1003) fills the bind :P11_INVOICE_ID of the report's queries with 1003.

In any PL/SQL: a process, a package, a job

PL/SQL
declare l_pdf blob; begin -- the page items of the queries come from session state l_pdf := pdf_api.generate('INVOICE');-- or give the values yourself l_pdf := pdf_api.generate('INVOICE', apex_t_varchar2('P11_INVOICE_ID', 1003));-- store it update invoices set pdf = l_pdf where invoice_id = 1003; end;
Chapter 6 · Dialog

Show the PDF in a dialog

Three declarative pieces, and no JavaScript: an application process that sends the PDF, a modal page with a URL region, and a link or button that opens it.

In the demoPage 92 Invoice PDF, the process INVOICE_PDF, and the Preview links of the Invoices report.

1. An application process

Shared Components > Application Processes, point Ajax Callback, name INVOICE_PDF:

PL/SQL
pdf_api.download('INVOICE', p_params => apex_t_varchar2('P11_INVOICE_ID', :P92_INVOICE_ID), p_filename => 'invoice-' || :P92_INVOICE_ID || '.pdf');

2. A modal page with a URL region

  • A new page, Page Mode: Modal Dialog, e.g. page 92 Invoice PDF, with a hidden item P92_INVOICE_ID.
  • One region of type URL, Inclusion Mode IFrame, URL:
URL of the region
f?p=&APP_ID.:0:&SESSION.:APPLICATION_PROCESS=INVOICE_PDF
IFrame attributes
style="width:100%;height:calc(100vh - 70px);border:0"

3. Open it from a report or a form

  • A column link of an interactive report: Target page 92, Set Items P92_INVOICE_ID = #INVOICE_ID#.
  • A button of a form page: Action Redirect to Page in this Application, page 92, Set Items P92_INVOICE_ID = &P11_INVOICE_ID.

APEX opens it as a dialog because page 92 is a modal page.

Invoice PDF
An APEX modal dialog showing an invoice PDF
Chapter 7 · New tab

A new tab, or a download

The same application process opens in a new browser tab. A second process with p_inline => false downloads the file instead of showing it.

A "New tab" button

Action Redirect to URL, target:

URL of the button
javascript:window.open('f?p=&APP_ID.:0:&SESSION.:APPLICATION_PROCESS=INVOICE_PDF:::P92_INVOICE_ID:&P11_INVOICE_ID.', '_blank');

A download

Application process INVOICE_DOWNLOAD
pdf_api.download('INVOICE', p_params => apex_t_varchar2('P11_INVOICE_ID', :P92_INVOICE_ID), p_filename => 'invoice.pdf', p_inline => false);
Chapter 8 · More

Batches, labels, e-mail and REST

The PDF is a BLOB in the database, so it goes wherever PL/SQL goes.

All the invoices of a period in one PDF

In the report's properties, One document per row of Q1. The other queries read the current row as :Q1_INVOICE_ID, and the page numbers restart for every invoice.

PL/SQL
l_pdf := pdf_api.generate('INVOICE_BATCH', apex_t_varchar2('P10_DATE_FROM', '01-SEP-2026', 'P10_DATE_TO', '30-SEP-2026'));

Labels on a sheet that is partly used

PL/SQL
-- 24 labels of one product, starting on the 5th label of the sheet l_pdf := pdf_api.generate('PRODUCT_LABELS', apex_t_varchar2('P30_SKU', 'NW-GLV-100', 'P30_COPIES', 24, 'LABEL_START', 5));

E-mail it

PL/SQL
declare l_id number; begin l_id := apex_mail.send(p_to => 'customer@example.com', p_from => 'billing@example.com', p_subj => 'Your invoice', p_body => 'Please find your invoice attached.'); apex_mail.add_attachment( p_mail_id => l_id, p_attachment => pdf_api.generate('INVOICE', apex_t_varchar2('P11_INVOICE_ID', 1003)), p_filename => 'invoice.pdf', p_mime_type => 'application/pdf'); apex_mail.push_queue; end;

A REST endpoint with ORDS

A GET handler of source type Media Resource returns the PDF to any client:

ORDS handler
select 'application/pdf', pdf_api.generate('INVOICE', apex_t_varchar2('P11_INVOICE_ID', :id)) from dual
Architecture

Pure PL/SQL, from your query to the PDF bytes

No Java, no print server, no JavaScript library makes the PDF. It is written byte by byte by PL/SQL inside the database, so it runs wherever Oracle Database and APEX run.

1
Your APEX applicationcalls pdf_api.generate or pdf_api.download
2
PDF_APIruns the report's queries with your schema's rights and your page items
3
PDF_ENGINElays out bands, tables, groups, totals, labels and page numbers
4
PDF_WRITERwrites the PDF: fonts with their metrics, shapes, JPEG images
~30 msfor a one-page invoice, logo and table included
1 callpdf_api.generate returns the BLOB
Freeon GitHub, with no server or service to add
10queries per report, with your page items

Your data stays home

The PDF is made where the data is. Nothing is sent to an outside service.

Your schema's rights

The API has invoker rights: every application reads only its own tables.

Logged

Every PDF made is logged: report, user, pages, size and time.

Portable reports

A report is a JSON layout and its queries: export, import, keep it in git.

Design it once. Print it from any page in APEX. No BI Publisher, no Word templates, no print server.

Get VinAura PDF
  • The designer application
  • The PL/SQL engine and API
  • Demo screens and sample reports
FAQ

Frequently asked

Anything else? Open an issue on GitHub.

Do I need BI Publisher, a print server or APEX Office Print?

No. VinAura makes the PDF in PL/SQL inside your database. There is nothing to install or run beside Oracle and APEX.

Which versions of Oracle and APEX does it need?

The engine and the API need Oracle Database 19c or later with Oracle APEX. The designer application is an Oracle APEX 26.1 export, so the workspace where you design needs APEX 26.1 or later.

Does it work on Autonomous Database?

It is built for it: plain PL/SQL and SQL, with no operating-system access, no Java, no files and no network calls, so it uses nothing that Autonomous Database restricts.

Can my page items be used in the queries?

Yes. A bind variable such as :P11_INVOICE_ID takes the value of that page item from session state, or the value you pass to pdf_api.generate.

Where are the layouts kept?

In tables of your schema: PDF_REPORTS (the layout, as JSON) and PDF_QUERIES. A report can be exported as JSON and imported into another environment.

Which fonts and characters does it print?

Helvetica, Arial, Arial Narrow, Arial Black, Times and Courier, in regular, bold and italic, with the characters of Western European languages. The rupee sign prints as Rs.

How fast is it, and how big are the files?

A one-page invoice with a logo takes about 30 ms and is about 35 KB. A batch of invoices is one call and one file.

Is it free?

Yes. VinAura is free on GitHub. Download it, install it in your workspace, and change it to fit your applications.

What is in the repository?

The APEX application export (dist/pdf_report_designer.sql), the SQL scripts of the tables and packages, the demo data and sample reports, the source of the designer, and the installation guide (docs/INSTALL.md).

Get VinAura PDF

Free on GitHub

VinAura is on GitHub, free to download. Take the whole project, install it in your development workspace, fork it and change it as you need.

  1. Open the repositoryOn GitHub: devvinish/pdfgen-apex.
  2. Download or clone itCode > Download ZIP, or git clone.
  3. Install itFollow docs/INSTALL.md, or chapter 1 of the tutorial above.
github.comdevvinish / pdfgen-apex
Public

VinAura, the visual PDF report designer for Oracle APEX: the designer application, the PL/SQL engine and API, demo screens and sample reports.

  • dist/the APEX application to import
  • sql/tables, packages, demo data, sample reports
  • docs/INSTALL.mddevelopment and production installs
  • app/the designer's JavaScript and CSS
Open on GitHub
Or clone it
git clone https://github.com/devvinish/pdfgen-apex.git

00