VinAura is developed by Vinish Kapoor. This repository (pdfgen-apex) holds the complete project.
Design PDF documents (invoices, statements, labels, reports) on a canvas, bind them to SQL queries and generate them from any APEX application with one PL/SQL call. No BI Publisher, no Word templates, no print server: everything runs inside the database.
See it first: screenshots of the designer, sample PDFs and a step-by-step tutorial are on vinish.dev: VinAura, the PDF report designer for Oracle APEX.
l_pdf := pdfgen.pdf_api.generate('INVOICE'); -- page items from session state
l_pdf := pdfgen.pdf_api.generate('INVOICE', apex_t_varchar2('P11_INVOICE_ID', 1003));
pdfgen.pdf_api.download('INVOICE'); -- straight to the browserWhat the database and APEX need for development and production, with or without the demo tables and data: docs/INSTALL.md.
New to VinAura? The tutorial walks through a first report: the queries, the layout, the PDF in a dialog, and moving reports to production.
| Schema | PDFGEN (added to the APEX workspace HOSPORA) |
| Application | 2000 "PDF Report Designer" (APEX accounts login), alias PDF_DESIGNER |
| Local test copy | 2099, no login (for automated testing only), alias PDF_DESIGNER_TEST |
| Export to import anywhere | dist/pdf_report_designer.sql (application + supporting objects) |
The pages: Reports (list, New Report, an Import dialog, Export JSON), Designer, Try the API, Deploy (a SQL script that moves reports and their images to production), Log, How to Use, and the Demo menu:
| Page | |
|---|---|
| 10 Invoices | IR with a Preview (dialog) link per row; batch PDF of a period (INVOICE_BATCH) |
| 11 Invoice | header form + lines grid (add/change/delete lines), totals, Preview / New tab / Download |
| 20 Customers, 21 Customer | IR and form; the statement of account (CUSTOMER_STATEMENT) per customer |
| 30 Products, 31 Product | IR and form; one shelf label of a product, or the labels of a category (PRODUCT_LABELS) |
| 92–96 PDF dialogs | Invoice, Statement, Label, Labels of a category, Invoices of a period. Each has its own items (P92_INVOICE_ID, ...) set by the caller and a URL region (iframe) on its application process, e.g. INVOICE_PDF = pdf_api.download('INVOICE', apex_t_varchar2('P11_INVOICE_ID', :P92_INVOICE_ID)) |
The demo pages are generated by tools/demo_pages.py.
- Queries Q1..Q10 with bind variables (
:P11_INVOICE_ID). A query is checked when you leave it: its columns become draggable Fields, its binds become Parameters (test values for Preview). - Bands: Page Header, Report Header, Body (flows over pages), Summary, Page Footer. Label layouts have one Label band, repeated across and down.
- Elements: text (with tokens), box, rounded box, ellipse, line, image, table, Code 128 barcode. Drag, resize, align, snap to grid, copy/paste, undo/redo, keyboard nudging.
- Tables: columns from fields or text with tokens, widths, alignment, format masks, totals (sum/count/avg/min/max), group-by with headings and sub-totals, zebra rows, grid lines, header row repeated on every page, rows that grow with long text.
- Page setup: A3, A4, A5, A6, B5, Letter, Legal, Tabloid, Executive, envelopes, or a custom size; portrait/landscape; margins; units mm/in/pt.
- Print when conditions, e.g.
{Q1.STATUS} = PAID. - One document per row of Q1 (batch printing): other queries read
:Q1_<COLUMN>.
Tokens: {Q1.COL}, {Q2.AMOUNT|FM999G990D00}, {SUM(Q2.AMOUNT)}, {COUNT(Q2)}, {WORDS(Q3.TOTAL)}
(Indian lakh/crore; |INTL for million), {PAGE}, {PAGES}, {TODAY}, {NOW}, {APP_USER},
{REPORT}, {P11_ITEM}.
| File | |
|---|---|
10_tables.sql |
PDF_REPORTS (code, name, layout JSON), PDF_QUERIES, PDF_IMAGES (JPEG), PDF_LOG |
20_pdf_writer.sql |
PDF_WRITER: the low-level PDF 1.4 writer (standard fonts with metrics, WinAnsi text, lines, rectangles, rounded rectangles, ellipses, JPEG, clipping) |
30_pdf_engine.sql |
PDF_ENGINE: the layout engine (bands, flow, tables, groups, totals, tokens, labels, barcodes, page numbers) |
40_pdf_api.sql |
PDF_REPO (definer rights; also the report import used by deploy scripts) and PDF_API (invoker rights: queries run as the calling schema) |
45_pdf_designer.sql |
PDF_DESIGNER: the Ajax calls of the designer, create/copy/export/import, deploy scripts |
50_demo_data.sql |
PDF_DEMO_* tables: 12 customers, 20 products, 35 invoices; view PDF_DEMO_INVOICE_LINES_V |
60_samples.sql |
the sample reports INVOICE, INVOICE_BATCH, PRODUCT_LABELS, CUSTOMER_STATEMENT and the demo logo (generated by tools/samples.py; added only when missing, never overwritten) |
Other schemas use the API with grant execute on pdfgen.pdf_api to <schema> and a synonym.
tools/db.sh schema # create PDFGEN (once)
tools/db.sh run sql/*.sql # install / update the objects, list compile errors
python3 tools/samples.py # rewrite sql/60_samples.sql from the Python layouts
python3 tools/gen_app.py # dist/ export + local/ no-login test copy
python3 tools/apex/check_export.py dist/pdf_report_designer.sql # verify against the 26.1 vocabulary
tools/db.sh import dist/pdf_report_designer.sql 2000
tools/db.sh import local/pdf_report_designer_test.sql 2099
tools/getpdf.sh "select doc from pdf_test_out where id = 1" local/out/x.pdf # save a BLOB you stored in a scratch tableThe designer front end is app/designer.js and app/designer.css (application static files); the
How to Use page is app/help.html. local/ (passwords, logs, test output) is not part of the project.
- Fonts: the 14 standard PDF fonts, plus Arial, Arial Narrow and Arial Black as look-alikes made from
Helvetica. The rupee sign prints as
Rs.; Hindi and other scripts need embedded TrueType fonts (a next step). - Characters: one code page per report (Page setup > Characters): Western European (default), Central European (Croatian, Czech, Polish, Slovak, Slovenian, Hungarian, Romanian), Baltic or Turkish. Greek, Cyrillic and mixed scripts need embedded fonts.
- Images are JPEG (uploads are converted in the browser). Barcodes: Code 128 (QR is a next step).
- Content streams are not compressed (a one-page invoice is about 30 KB).
- A table row is never split across pages.
VinAura is free to use under the PolyForm Shield License 1.0.0. Copyright (c) 2026 Vinish Kapoor.
- You may: use it free of charge, personally or in your company, and inside your own applications, including commercial ones (for example an ERP that prints its invoices with VinAura). You may change it and share it.
- You may not: sell or offer VinAura itself, or a product built from it that competes with it (another PDF report designer or reporting tool), whether paid or free.
- Keep the copyright notice (
Required Noticein LICENSE.md) with any copy you pass on. - It comes as is, without any warranty. See the licence for the full terms.
This project doesn't accept pull requests. Please report bugs and ideas as Issues. You're welcome to fork it under the terms of the licence.
Security problems: see SECURITY.md.