Product documentation

ApexReporter Studio

A visual, band-based report designer and self-hosted runtime built specifically for Oracle Database — everything you need to plan a rollout, install it, configure it, integrate it with Oracle APEX, and run it in production.

Applies to ApexReporter Studio, current release Data source: Oracle Database 11g – 23ai Platforms: Windows & Linux

What, why & how

What it is

ApexReporter Studio is a visual, drag-and-drop, band-based report designer and runtime for Oracle Database — the same design language as Oracle Reports Builder (report/page headers and footers, group headers and footers, a detail band) rebuilt as a modern browser application. You design a report once against a live Oracle query and publish it to PDF, Excel, Word, PowerPoint, CSV, or HTML, on demand or on a schedule.

It ships as two cooperating processes: a browser-based designer (the application you interact with) and a self-hosted server that talks directly to your Oracle database and renders the final output. Everything runs on infrastructure you control — nothing about your report data or your database credentials passes through a third party.

Why it exists

Organizations that built their operational reporting on Oracle Reports and Oracle Forms are past due for a modernization plan — vendor direction has moved away from those tools, and the alternative most teams reach for is a general-purpose BI product that doesn't understand Oracle Reports Builder concepts (bands, PL/SQL lifecycle triggers, format masks, bind-variable parameters) and doesn't integrate cleanly with an existing Oracle APEX estate. ApexReporter Studio is purpose-built to close that gap: a familiar band-based design surface for teams who already think in Oracle Reports terms, native Oracle connectivity with no separate client install, and first-class Oracle APEX invocation built in from day one.

How it works

At a high level:

  1. The designer (your browser) is where you connect to Oracle, write or generate a query, and lay out a report visually.
  2. Saved reports, users, schedules, and version history are tracked by the server in a small embedded metadata database — no separate database server to install or license for the tool itself.
  3. When you preview, export, or a scheduled job fires, the server runs your query against Oracle directly (in thin mode — no Oracle Instant Client required) and renders the result into the requested output format.
  4. Reports can be triggered interactively from the designer, on a cron schedule with automated delivery, or invoked remotely — including directly from an Oracle APEX page.
Oracle-only, by design

Oracle Database is the only officially supported data source. This keeps the product deeply Oracle-aware — bind-variable syntax, PL/SQL triggers and Program Units, EZConnect/TNS connectivity — rather than a shallow lowest-common-denominator layer across many databases.

How it compares

Three tools sit in the same general space — designing a formatted, data-driven document and getting it out to users — but they solve that problem in genuinely different ways. This is a straight technical comparison, not a marketing claim: pick the row that matches what you actually need.

Dimension Oracle Reports Builder 12c JasperReports Server ApexReporter Studio
Design surface Desktop Windows client (Reports Builder), thick-client only, Java Runtime dependency for the deployed Forms/Reports stack. Jaspersoft Studio (Eclipse-based desktop) for report design; the Server component is a separate Java/Tomcat web app just for hosting, scheduling, and viewing already-built reports. Fully browser-based — the design surface is the web app. No separate desktop designer to install, license, or keep patched.
Data source model Oracle-native by design — direct OCI connectivity, bind parameters, PL/SQL anonymous blocks and stored Program Units as first-class citizens. Database-agnostic by design — JDBC to almost anything (Oracle, Postgres, MySQL, SQL Server, etc.), plus POJO/bean, CSV, JSON, and custom data-source adapters. Oracle-only, deliberately (see "Oracle-only, by design" above) — same bind-variable/PL/SQL vocabulary as Reports Builder, rebuilt for the browser. Not a multi-database tool.
Report definition format Proprietary binary/XML .rdf/.jsp/.rep files, compiled and deployed to a Reports Server. Open XML .jrxml, compiled to .jasper at runtime or deploy time — widely documented, portable across JasperReports-compatible tools. JSON report definitions stored in an embedded metadata store; imports existing .jrxml (JasperReports) and Oracle Reports Builder's own structure XML directly, so neither prior investment is a dead end.
Layout model Band-based: Report/Page Header-Footer, Group Header-Footer, Detail — matrix and group-left/group-above layout styles. Band-based: Title, Page Header/Footer, Column Header/Footer, Group Header/Footer, Detail, Summary, Background — a superset of Reports Builder's band vocabulary. Same band vocabulary as Reports Builder (Report/Page/Group Header-Footer, Detail), plus a dedicated Dashboard report type that abandons pagination for a fit-to-screen kiosk layout — a band JasperReports/Reports Builder don't have.
Rich elements Text, fields, boxes/lines, images, matrix (cross-tab), OLE objects, PL/SQL-drawn graphics. Very broad: charts, crosstabs, tables, subreports, barcodes, maps, sparklines, custom components via a plugin API — the most extensive built-in element library of the three. Charts (16 types), crosstab, list/card layout, 20+ barcode symbologies, live OpenStreetMap embed, subreports, KPI cards — deliberately not as exhaustive as Jasper's plugin ecosystem, but covers the elements Oracle Reports customers actually ask for.
Output formats PDF, HTML, RTF, PostScript, delimited text, XML (Reports Server-side). PDF, HTML, XLS/XLSX, RTF, ODT, ODS, CSV, DOCX, PPTX, XML, plain text — broadest export matrix of the three. PDF, HTML, Word (DOCX), PowerPoint (PPTX), Excel (XLSX, with a streaming/large-dataset path), CSV.
Scheduling & delivery Reports Server job queue; delivery via Oracle Reports' own distribution options (file, printer, e-mail with additional configuration). Built-in scheduler UI on the Server product, with repository-based output storage, e-mail delivery, and a REST API for job management. Cron-based schedules (presets or raw cron expressions) with Email/FTP/SFTP delivery, run history per job, and an on-demand "Run Now" override.
APEX / web integration Not designed for it — Reports Server predates Oracle APEX; integration means calling the Reports Server's own CGI/servlet URL scheme by hand. REST API and an embeddable viewer exist, but nothing APEX-specific — an APEX developer wires it up the way they would any external Java web service. First-class from day one: a small JS client (ApexReporter.run() / .preview()) built specifically for an APEX page's Dynamic Actions, plus REST endpoints an ORDS/APEX backend can call directly.
Deployment footprint Oracle Fusion Middleware / WebLogic install — the heaviest of the three; typically bundled with a broader Forms & Reports infrastructure. Java + Tomcat/app-server + its own repository database — a full middle-tier stack dedicated to reporting. A single Node.js process plus an embedded SQLite-based metadata store — no application server, no separate repository database to provision.
Vendor direction Maintenance mode — Oracle has publicly signaled Forms & Reports are not the strategic path forward for new development. Actively maintained (TIBCO/Cloud Software Group), but as a general BI platform, not an Oracle-modernization tool specifically. Actively developed, purpose-built as the modernization target for existing Oracle Reports/Forms estates that also run Oracle APEX.
How to read this table

JasperReports Server is the right choice when the requirement is genuinely multi-database BI with the widest possible plugin/element ecosystem. Oracle Reports Builder is what you already have, and this table exists to show what changes if you move off it. ApexReporter Studio's bet is narrower and specific: teams who are Oracle-only, already think in Reports Builder's band/PL/SQL vocabulary, and want that same mental model back — in a browser, wired natively into Oracle APEX — without taking on a general-purpose BI platform's footprint or a multi-database abstraction layer they don't need. See the reporting-tool buyer's guide for a shorter version of this same decision, and the main site's APEX Interactive Reports comparison for how this differs from what APEX itself already ships.

Platform & requirements

Operating systemWindows 10/11 or Windows Server 2019+; any modern 64-bit Linux (Ubuntu 20.04+, Debian 11+, RHEL/Rocky/Alma 8+, Amazon Linux 2023, and similar). macOS also runs the same commands as Linux.
CPU / RAM2 cores / 4 GB RAM minimum; 8 GB+ recommended if you also run a local Oracle instance on the same machine.
Disk space~1.5 GB free for the runtime, installed packages, metadata storage, and logs.
RuntimeNode.js 22.5.0 or later (the embedded metadata store requires this version specifically — see Installation).
NetworkOutbound HTTPS during setup and for AI-assisted features; inbound access only required if other machines need to reach the app.
Ports4000 (API/server) and 5173 (designer UI, development mode) by default — both configurable. A packaged production deployment serves everything from a single configurable port.
DatabaseOracle Database 11g – 23ai for real data. Not required to evaluate the product — a built-in demo dataset (sample employee/department data) works out of the box with zero setup.
Oracle client softwareNot required. Connections run in Oracle's "thin mode" — pure network protocol, no Oracle Instant Client installation.
BrowserAny current version of Chrome, Edge, Firefox, or Safari.
Why Node 22.5.0 specifically

The embedded metadata store uses Node's native SQLite module, which does not exist before Node 22.5.0. Versions 22.5.0–23.3.x additionally need a startup flag that the provided launch scripts set automatically; Node 23.4.0 and later enable it by default. Using the provided start scripts means you never need to think about this directly.

Installation

ApexReporter Studio installs the same way on Windows and Linux: unpack it anywhere on disk, run the provided launch script, and it bootstraps its own configuration, installs its dependencies, and starts. Installing specifically alongside an existing Oracle APEX/ORDS mid-tier, with the APEX-page wiring steps included? See the Oracle APEX installation guide.

Windows

  1. Install Node.js 22.5.0 or later (LTS installer from nodejs.org, or winget install OpenJS.NodeJS.LTS).
  2. Extract ApexReporter Studio to an install folder of your choice.
  3. Open PowerShell in that folder and run .\start.ps1.
  4. On first run this creates the configuration file from its template, installs dependencies, and launches the designer in your default browser once it's reachable.

Linux

  1. Install Node.js 22.5.0 or later — via your distribution's NodeSource repository is recommended over an older distro-bundled version.
  2. Extract ApexReporter Studio to an install directory.
  3. Make the scripts executable once: chmod +x start.sh stop.sh
  4. Run ./start.sh. Behavior mirrors Windows: configuration bootstrap, dependency install, then launch. Add NO_BROWSER=1 on a headless server.

Production deployment

For a persistent, production installation, ApexReporter Studio packages into a standalone runtime: a single compiled Node.js process that serves both the API and the compiled designer application from one port — no separate dev server. Run it under a process manager so it survives reboots and crashes:

Windows

Run as a Windows Service (e.g. via NSSM) or under IIS as a reverse-proxied Node process.

Linux

A systemd unit with Restart=on-failure, or a process manager such as pm2.

Put a reverse proxy (nginx, IIS, or Oracle ORDS/HTTP Server) in front to terminate HTTPS — the application itself speaks plain HTTP and expects TLS to be handled at that layer.

Verifying the install

A healthy installation, checked in order:

  1. GET /api/health returns a JSON status — confirms the server process is up.
  2. The designer loads in a browser and shows the login screen.
  3. Signing in with the administrator account loads the designer shell — toolbar, palette, canvas, properties panel.
  4. The built-in demo connection returns rows for a sample query — confirms the full client-to-database path works without needing a real Oracle instance.
  5. A report can be designed, saved, previewed, and exported to PDF.

Configuration

Every deployment-level setting lives in one plain-text file, config.ini, at the root of the install — the single place to look, read at startup. Restart the application after editing it.

SectionControls
[server]API port, and where application data (database, uploaded assets, logs) is stored.
[client]Designer UI port and, for advanced reverse-proxy deployments, the sub-path it's served under.
[admin]Sets or resets the built-in administrator account's password without touching any other data.
[security]Allowed browser origins (CORS), the trusted service-caller API key for external integrations, and the encryption key protecting saved connection passwords at rest.
[smtp]The outbound email account used by scheduled report delivery.
[delivery]The FTP/SFTP target used by scheduled report delivery.
[logging]Log verbosity and whether/where plain-text log files are written.
[render]Which engine generates PDF output — see PDF rendering engine below.
[ai]Enables AI-assisted SQL and expression generation.
[license]The activation key that unlocks the application — see Licensing & plans.

Administrator password

On a brand-new install, the value in [admin] password becomes the initial administrator password (leave it blank and one is generated and shown once in the startup console). On an existing install, changing this value and restarting resets only that one account's password — every report, connection, schedule, and other user account is left completely untouched.

PDF rendering engine

[render] pdf_engine chooses how the "PDF" export button and the API's ?format=pdf generate PDF output. Default pdfmake: a pure-JS library with no extra download and no browser needed on the server — but it lays out every element itself, independently of the HTML Preview/Print path, so a PDF can differ subtly from what Preview shows (font metrics, table column widths, wrapping) and gets pdfmake's own native Acrobat sidebar bookmarks for Table of Contents entries.

Set it to chromium and PDF output is generated by printing the exact same HTML Preview renders through a real headless browser — the same mechanism the Print button already uses from your own browser — so PDF, Preview, and Print match pixel-for-pixel instead of approximating each other. The trade-offs: it needs a headless Chromium installed alongside the server (a one-time, manual npx puppeteer browsers install chrome in the server/ folder — never downloaded automatically, so the default install footprint never changes for anyone who doesn't opt in), uses more memory per render, and Table of Contents entries become plain in-document jump links instead of sidebar bookmarks (like HTML export). If the browser isn't installed or fails to launch for any reason, that render falls back to pdfmake automatically and logs why — PDF export is never broken by trying this. Switch back to pdfmake at any time; nothing else about the report changes either way.

Connecting to Oracle

Connection profiles are managed inside the designer itself (Connections panel), not in a config file. Each profile stores a display name, an EZConnect string or TNS alias, and credentials — passwords are encrypted at rest using the key configured in [security]. A built-in DEMO connection with sample data is always available and needs no configuration.

Before exposing this beyond your own machine

Restrict allowed origins in [security] cors_origin (never leave it wide open once real users are involved), put the application behind HTTPS via a reverse proxy, and treat the service-caller API key exactly like a production secret if you enable it.

Licensing & plans

ApexReporter Studio is licensed by activation key. Applying it isn't limited to editing config.ini before the first start: leave it blank and the application still starts, in a locked state (every feature disabled) with an on-screen activation prompt in place of the login screen — paste a key there and it applies immediately, no restart, and is saved back into config.ini for you. The same in-app entry point (the About panel, once signed in) is also how a plan is changed or renewed later. Only a key that's actually present in config.ini but fails to verify (expired, tampered, or hardware-mismatched) stops the application from starting.

Each activation key licenses one installation — a single physical or virtual machine — not a number of seats. Every Basic, Pro, or Enterprise plan's monthly and yearly price is per machine, up to that plan's user limit; running the same key on a second machine isn't supported. A key can optionally be hardware-locked to that one machine's fingerprint (see [license] hardware_key in Configuration) so it can't simply be copied to another server. If you don't have a key yet, that fingerprint is shown right on the activation screen itself (no login needed) so you can copy it and send it to your license issuer to request a hardware-locked key — it's also visible afterward in the About panel for renewals or additional machines.

Three plans — Basic, Pro, and Enterprise — cover every user on the installation (designers, viewers, and administrators alike count toward a plan's user limit; there's no separate unlimited-viewer tier). Every plan, including Trial, includes all four report styles (Tabular, Group Above, Group Left, Summary Only) and the Crosstab element — none of that is plan-gated. Basic is a single-connection, single-user plan covering PL/SQL functions and procedures, up to 30 reports. Pro adds multiple database connections, up to 5 users, version history, triggers, report page setup, single-report import/export, and up to 100 reports. Enterprise lifts every limit — unlimited users and reports — and adds report scheduling, custom fonts, and bulk export/import of all reports at once. Custom DB Host, Alternate DB Engines (PostgreSQL/MySQL), the JasperReports XML export, and the two migration importers are separate one-time plug-in purchases available on any plan — see Plug-ins & migration. A Custom plan is also available, quoted per deployment, for multi-machine/site-wide licensing and every migration/connectivity add-on bundled in rather than billed separately. See the pricing section on the main site for the full feature comparison and current rates.

Want to try the designer itself first? A live hosted demo — no install, no signup — is always available at apex-reporter.com/studio. To evaluate against your own Oracle instance instead, see Trial installer below.

A plan or seat-count change made from the About panel takes effect immediately across the running application — no downtime, no reinstall.

Trial installer

build-installer.ps1/.sh produce a second, self-contained package alongside the normal one: a trial installer, downloadable from the main site (latest-trial.zip), that needs no activation key and no login at all — it opens straight into the designer as a single built-in user. It's meant to let a prospect evaluate the product against their own Oracle instance, not to run in production or for commercial use.

Reports

Up to 5 created in that installation, ever.

Database connections

1.

Migration imports

1 Oracle Reports (XML) + 1 JasperReports (JRXML), ever.

Everything else

Parameters, variables, scheduling, custom fonts, dashboards, version history, and personal folders are all fully open — Enterprise-equivalent, not the older Trial plan tier's tighter defaults.

Every exported file (PDF/Excel/Word/PowerPoint/CSV/HTML/JSON) and the in-app live Preview carry a permanent "APEX Reporter Studio - Trial Usage Only" watermark or disclaimer that cannot be removed. Report-definition export/import (.aprep) and JasperReports XML export are disabled — reports can't be moved out of or into a trial install — and the Administration area and API key management are hidden, since there's no login to administer.

Removing the trial flag doesn't unlock it

If config.ini's [trial] enabled=true is ever removed or set to false — and a trial install has no real activation key — the application falls back to the same locked activation-key screen a normal installation shows with a blank key, not an unlocked app. This is existing, unmodified license-lock behavior, reached a different way.

Installing the trial, step by step

The trial zip includes an INSTALLATION.txt with the full walkthrough (prerequisites, Windows and Linux commands, connecting to Oracle, firewall, troubleshooting, uninstall); in short:

  1. Install Node.js 22.5.0 or later (winget install OpenJS.NodeJS.LTS on Windows; NodeSource packages on Rocky/RHEL/Ubuntu) — no Oracle Instant Client, Docker, or build tools needed. Needs about 2 cores, 4 GB RAM, and 1.5 GB disk.
  2. Unzip the trial anywhere. Everything it creates lives in that folder under server/data/, so removing it later is just deleting the folder.
  3. Quickest: run the guided setup wizard — .\install.ps1 on Windows, or chmod +x *.sh && ./install.sh on Linux — it asks for the install path and port, then starts it for you. Or start it directly with no prompts: .\start-runtime.ps1 on Windows, or ./start-runtime.sh on Linux. The first start downloads dependencies (needs internet); later starts take seconds.
  4. Browse to http://localhost:4000 — no sign-in, no key. Try the built-in DEMO connection first, then add your one Oracle connection from the Connections panel.
  5. Optional: change the port in config.ini's [server] section (leave [trial] alone), open that port in the OS firewall for other machines, and restart. Stop with stop-runtime; keep your work with backup-data.

This is a good-faith evaluation gate, not copy protection: a trial install is still a self-hosted, source-shipped Node application with full filesystem/database access on the evaluator's own machine. See the reporting-tool buyer's guide for help deciding which plan to move to afterward.

Ready to move past the trial limits? Visit apex-reporter.com to purchase a Basic, Pro, Enterprise, or Custom plan, or use the Contact Us form to talk to sales first — the trial installer's own README repeats this same link.

Core components

Bands

A report is built from bands, the same structure as Oracle Reports Builder: Report Header, Page Header, any number of Group Headers, a Detail band, any number of Group Footers, Page Footer, and Report Footer. Groups can be nested, and a page break can be forced on any group boundary.

Elements

Seventeen element types can be placed on any band:

TextRich TextFieldImageLineRectangleEllipsePage NumberCurrent DateChartCrosstabTableTable of ContentsListMapKPI CardBarcode / QRSubreportHTML

Subreports nest recursively, with parent-to-child parameter mapping, so a master/detail layout is built the same way you'd expect from Oracle Reports Builder.

Report styles

The report wizard scaffolds a starting layout in one of ten styles, and any of them can be freely edited afterward on the canvas like any other report:

StyleWhat it produces
Tabular / ListA flat grid of rows, one per query result — the common case.
Group AboveRows grouped under a header band per group value, subtotals in a matching group footer.
Group LeftThe same grouping, with the group label placed to the left of its rows instead of above them.
Summary OnlyNo row detail at all — just report-level totals/aggregates, for a dashboard-style rollup with no line items.
Master-DetailEach group starts on its own page with a boxed master block above its detail rows and subtotals.
Form / Single RecordOne record per page as labeled fields in two columns — certificates, letters, ID cards.
Matrix / Cross-TabA pivot table with a chosen row field, column field and Sum/Count/Average/Min/Max measure, plus totals.
Mailing LabelsAvery-style address labels (5160, 5161, 5163, 5164) printed several across per US Letter sheet.
Multi-Column (Newspaper)A compact list flowing down 2-4 columns per page, like a directory or price list.
Statement / LedgerOne page per account with debit, credit, a running balance and the closing balance.

Charts

The Chart element supports sixteen chart types — line, bar, column, area, combo, pie, donut, radar, scatter, bubble, gauge, funnel, waterfall, heatmap, treemap, and candlestick — rendered pixel-identically whether you're looking at the canvas, an HTML preview, or a generated PDF, and embedded as native, editable chart objects (not images) in PowerPoint exports for the chart types PowerPoint itself supports natively.

Crosstab

The Crosstab element pivots query rows into a row-header × column-header grid with an aggregated measure at each intersection (sum, count, average, min, or max) — the same shape as a spreadsheet pivot table, laid out and styled directly on the report canvas and rendered consistently across HTML, PDF, and every export format.

Bookmarks & Table of Contents

Any element can be flagged as a bookmark — its own resolved value becomes an entry title, and its real page number (from the report's own pagination) is filled in automatically. A Table of Contents element lists every bookmarked entry with its page number, usually placed in the Report Header. In HTML export, entries are clickable in-document jump links; in PDF export (with the default pdfmake engine — see Configuration's PDF rendering engine section), every bookmarked element separately gets a real Acrobat sidebar bookmark (navigation pane) — pdfmake's native outline support, not a hand-rolled approximation. Word, Excel, and PowerPoint show a plain placeholder for the Table of Contents element. If [render] pdf_engine=chromium is set, PDF entries are clickable in-document jump links like HTML export, not sidebar bookmarks — the one visible trade-off of that engine.

Growing bands & page splitting

Any band can be marked Dynamic height so a Text/Field/HTML/Rich Text element with wrapping on can grow past its designed size instead of clipping. The report engine estimates the grown height from the wrapped content and reserves that much real space for it — later bands move down, and if a band won't fit what's left of the current page, it starts a fresh one instead of overlapping the next band. This works the same way in HTML and PDF export. The estimate keeps a band's content together on one page (a very long block moves the whole band to a new page rather than splitting mid-paragraph across two).

Table (tablix)

The Table element is a real grid — bound columns, a header row that repeats on every printed page, and an optional subtotal row after each change of a chosen group column plus a grand-total row, the same "tablix" shape SSRS and Crystal Reports call a table/matrix. Unlike the Crosstab, rows aren't pivoted into columns — it's a straight list with real column headers, closer to a spreadsheet than a pivot. Place it in a flat Detail band with no data source of its own and it renders as ONE table over every query row — header once (repeated at the top of each printed page), then all the records — instead of once per row. Choosing a Data source, or dropping a fresh Table, fills in every column automatically (Add all columns re-does it later); trim or reorder from there. The grand total prints once, on the last page. Date and timestamp columns show as DD-MON-YYYY by default (never a long date string) and each column has its own Date format choice (DD/MM/YYYY, YYYY-MM-DD, with time, and so on). Tables grow with their rows, and anything placed below a table in the same band — another Table, a total, a footnote — is pushed down to start after it instead of overlapping it. When the first table runs on the report's own query and spans several pages, a title above it stays on page 1, the header repeats at the top of each continuation page, and whatever sits below it (a second table, totals, a note) appears once, after the last row. Each column also has an optional Width (px) — leave it blank and columns share the table's width equally; set it on any column whose content (long text, a wide unformatted value) would otherwise push the table past the page. Cell borders are configurable too — solid (default), dashed, dotted, or turned off entirely, with its own width and color, in the table's own properties (not per column, since a table's grid lines are all one style).

Parameters, variables & formulas

  • Parameters — user-supplied input used to filter what a report returns at run time. Each parameter picks its own runtime control (text, number, date picker, checkbox, radio group, single-select list of values, or multi-select), and an LOV's choices can be a static display/return list or a live SQL query against the report's connection — including cascading LOVs, where one list re-runs whenever another parameter changes.
  • Bind vs. lexical references — reference a parameter as :P_NAME for a safely-bound scalar value, or as &P_NAME (Oracle Reports Builder-style) to splice its raw text into the SQL before it runs — dynamic column lists, table names, whole WHERE/ORDER BY clauses, and multi-select IN (&P_DEPTS) expansion. Works in the main query, named queries and subreport queries.
  • Variables — running calculations (sum, count, average, min, max, or a custom formula) that reset at the report, page, or group level, e.g. a group subtotal or a grand total.
  • Formulas — named, reusable per-row expressions defined once and dragged onto a band exactly like a query column, e.g. an "Annual Salary" formula computed from a monthly salary field.

Data source & connections

A report's data source is a SQL query (or a stored procedure/ref cursor), run against a connection profile using standard named-bind syntax. Oracle is the native, always-available engine (EZConnect/TNS, thin mode, no client install); a connection can also be a CSV or JSON file (uploaded once, then queried with real SQL — including bind-variable filtering — against an in-memory table, not a bespoke file reader) with no plug-in required; PostgreSQL and MySQL are available via the Alternate DB Engines plug-in (see Plug-ins & migration). A built-in DEMO connection (Oracle's classic EMP/DEPT tables) needs zero setup. The Query panel offers a live preview against real data while you design, and an AI-assisted "Generate with AI" option that turns a plain-English description into a starting query.

Links & drill-through

Any element can carry a Link — a URL template where {FIELD} tokens are filled from the current row (URL-encoded), such as https://erp.example.com/orders/{ORDER_ID}. The element becomes clickable in HTML output, and Text/Field elements are clickable in PDF too. Use it to jump to another system or to open another report with a parameter taken from the clicked row. Only http(s), mailto and relative targets are honored.

Conditional formatting & style templates

Any element can carry one or more conditional formats — a condition expression (e.g. {SAL} > 5000, the same small evaluator used for expressions and formulas) paired with a style override (colour, background, font, border) that applies only when the condition is true at render time — a bound cell that turns red when a value crosses a threshold, without a separate PL/SQL trigger. Separately, a style template is a named, reusable set of style properties saved once at the report level and applied to any element from the Properties panel's Apply dropdown — a fast way to keep look-and-feel consistent across many elements instead of re-setting font/colour/border by hand on each one.

Selection, alignment & keyboard shortcuts

Multiple elements can be selected at once — shift/ctrl-click, or a marquee drag across the canvas — and every Properties panel edit (style, geometry, format mask, and more) then applies to the whole selection simultaneously, not just the last-clicked element. A right-click on a multi-selection offers layer order (bring to front/forward/back), size, position, Align (left/center/right/top/middle/bottom), distribute (3+ elements), group/ungroup, and cut/copy/paste/delete; the same Align/distribute/group actions also appear as one-click buttons in the toolbar above the canvas whenever 2 or more elements are selected, so they don't require a right-click to discover. Standard shortcuts work as expected, same as any desktop reporting/design tool: Delete/Backspace removes the selection, arrow keys nudge it (Shift+arrow for 10px), Ctrl+C/Ctrl+X/Ctrl+V copy/cut/paste, Ctrl+D duplicates, Ctrl+G/Ctrl+Shift+G group/ungroup, Ctrl+]/Ctrl+[ bring forward/send backward, Ctrl+A selects every element in the active band, Ctrl+Z undoes, Ctrl+Y (or Ctrl+Shift+Z) redoes, Ctrl+O opens the Open Report dialog, Ctrl+P opens Preview, Ctrl+S saves from anywhere (even with a property field focused), and F1 opens context-sensitive Help. Every shortcut except Ctrl+S is suspended while typing in a text field so a field's own native copy/paste/undo still works normally there; Cmd replaces Ctrl on macOS throughout.

Every shortcut above (except arrow-key nudging) can be remapped to a different key combination from Administration → Shortcuts, open to every role — personal to your own account, not something an Administrator sets for anyone else, and it follows you to any device you sign in from. A remapped combo that collides with another shortcut is flagged right there in the list rather than silently shadowing it.

Feature functionality

Publishing & export

Every report, on every plan, can be previewed instantly as HTML, or exported to PDF (with true pagination, page breaks, and repeating group headers/footers), designer-fidelity Excel, Word, and PowerPoint, CSV, or raw JSON. Custom fonts (.ttf/.otf) can be uploaded and embedded directly into PDF and HTML output on the Enterprise plan.

Scheduling & unattended delivery (Enterprise)

Any report can be scheduled on a standard cron expression, with automatic retry and a full run history per job. Scheduling changes take effect immediately — no restart required. Delivery targets are Email (SMTP) or FTP/SFTP, configured once for the whole deployment; a job simply chooses recipients or a remote path within that configured target. A "Run Now" action executes a job on demand outside its schedule, useful for testing.

PL/SQL triggers & Program Units

Reports support the same five lifecycle trigger points as Oracle Reports Builder — Before/After Parameter Form, Before/After Report, and Between Pages — each a plain PL/SQL block run against the report's own connection at the matching point in rendering, whether the report is previewed, exported, or run on a schedule. Program Units let you author, validate, and compile PL/SQL functions and procedures directly against your Oracle connection from within the designer.

REF CURSOR / stored-procedure data sources

A report's data source (or any named query) can be a call to a PL/SQL function that returns a SYS_REFCURSOR, or a procedure with its own REF CURSOR OUT parameter, instead of a literal SQL statement — for data-assembly logic too complex to express as one SELECT. Write the call exactly as you would in PL/SQL; ApexReporter wraps and binds it automatically.

Placeholder variables

A report-scoped variable can be set purely by PL/SQL rather than derived from row data — Oracle Reports Builder's own Placeholder column idiom. Give it a PL/SQL function-call expression and it's evaluated once per render, its value available to any Field element like any other variable.

Parameter validation

Any parameter can carry a PL/SQL boolean validation expression, checked before any data is fetched — reject bad input with a clear, custom message instead of producing a bad or empty report.

AI-assisted authoring

Where enabled, "Generate with AI" turns a plain-English description into dialect-aware SQL for the Query panel, into a report expression for any bound field or formula, and into a PL/SQL function or procedure body in the Program Units editor — a starting point to refine, not a black box; the underlying code remains fully visible and editable. An Administrator configures the provider (Anthropic or Cohere) and API key live under Administration → AI Provider, with no restart.

Personalisation — appearance & defaults

Administration → Preferences (open to every role, saved per-user so it follows you between devices) has three groups. Interface changes how the studio itself looks — light / dark / follow-system, the typeface used across every panel and dialog, an overall interface size, and the accent colour — applied instantly. New-element defaults seed the font, size, colour, alignment, guide border and number/date format masks stamped onto every element you next add to the canvas (existing reports are never altered), plus a toggle for the post-login welcome screen that showcases the report types you can build. Ruler units set the unit the canvas's top and left rulers label their ticks in — independently per axis, so you can mix inches across the top with centimeters down the left, or use the same unit for both.

Version history (Pro and Enterprise)

Every save creates a new version rather than overwriting the last one — nothing is ever silently lost. Past versions can be browsed and reverted at any time; reverting itself creates a new version, so the version you reverted from stays in history too.

Portability (Pro and Enterprise)

A report's full design can be exported to a single portable file for backup or for moving between installations, and imported back in. Pro covers one report at a time; Enterprise adds exporting or importing every report on the installation at once.

Security & access control

Session-based authentication with six built-in roles (Administrator, Designer, Developer, Publisher, Runtime User, Viewer), a full audit trail of every meaningful action, per-report access restriction by role, and connection passwords encrypted at rest. A separate trusted service-caller key allows headless callers — most notably Oracle APEX — to invoke reports without an interactive login.

Personal API keys

Any signed-in user (any role) can generate their own personal API key from the toolbar's My API Key button, and revoke or regenerate it any time with no downtime for anyone else. Presented as X-Api-Key header or ?apiKey= query parameter, it authenticates the request as that specific user — useful for a plain link or script that needs to skip the login prompt — and is always bound by that user's own normal role and sharing permissions: a report that isn't shared with them still can't be rendered with their key, unlike the deployment-wide service-caller key described above, which bypasses per-user access control entirely.

Step-by-step walkthroughs

Concrete, do-this-then-that examples for the PL/SQL-facing and dashboard features above. Every example uses the built-in DEMO connection (Oracle's classic EMP/DEPT tables, no setup required) except where noted — Program Units, REF CURSOR data sources, Placeholders, and Parameter validation all compile/run real PL/SQL, so those need a genuine Oracle connection.

Program Units — a Function

  1. Toolbar → Program Units → + New Program Unit, name it AMT_IN_WORDS_FN.
  2. Kind: Function, return type VARCHAR2. Paste the full PL/SQL, header included:
    function AMT_IN_WORDS_FN(p_amount in number) return varchar2 is
    begin
      return to_char(to_date(trunc(p_amount), 'J'), 'JSP');
    end;
  3. Pick a connection, click Validate/Compile — status flips to VALID, or shows real Oracle compiler errors to fix.
  4. Use it in a query (SELECT e.*, AMT_IN_WORDS_FN(e.sal) AS SAL_WORDS FROM EMP e) or a Field's Expression box: {AMT_IN_WORDS_FN(SAL)}.

Before/After Report triggers

  1. Toolbar → Triggers — five tabs matching Oracle Reports Builder's own lifecycle points: Before/After Parameter Form, Before/After Report, Between Pages.
  2. Type plain PL/SQL, no BEGIN/END wrapper needed:
    -- Before Report
    LOG_RUN_PROC('Monthly Sales Report');
  3. Save. An exception raised by a trigger aborts the render with that error, exactly like Reports Builder.

REF CURSOR data source

  1. Toolbar → Data Source → Data source type → Function returning a REF CURSOR.
  2. Type the call as real PL/SQL — no SELECT, no BEGIN/END:
    pkg.get_dept_summary(:P_DEPTNO)
    This runs as BEGIN :cursor := pkg.get_dept_summary(:P_DEPTNO); END; — the returned cursor becomes the report's rows.
  3. For a procedure instead, include the literal :cursor placeholder yourself: pkg.get_dept_summary(:P_DEPTNO, :cursor).
  4. Click Run Preview to test before saving.

Placeholder variables

  1. Toolbar → Parameters & Variables → Variables → + Add Variable, name it TAX_RATE.
  2. Calculation → Placeholder (PL/SQL-set). Reset On locks to REPORT automatically — the only scope Placeholders support.
  3. Type a real PL/SQL function-call expression: pkg.get_current_tax_rate(:P_YEAR) — evaluated once per render as SELECT pkg.get_current_tax_rate(:P_YEAR) FROM DUAL.
  4. Reference it anywhere like any other variable: a Field's Field Name TAX_RATE, or {TAX_RATE} in an expression.

Parameter validation

  1. Toolbar → Parameters & Variables → Parameters → under the parameter, the Validation row takes a PL/SQL boolean: TO_NUMBER(:P_YEAR) BETWEEN 2000 AND 2099.
  2. Optionally set a custom error message — otherwise a generic one is shown.
  3. Cross-parameter checks work too (bind every submitted parameter by name), e.g. on a second parameter: TO_DATE(:P_END_DATE,'YYYY-MM-DD') >= TO_DATE(:P_START_DATE,'YYYY-MM-DD').
  4. A failed validation rejects the whole render before anything is fetched — no partial/bad report is ever produced.

KPI Card

  1. Add a named query (Toolbar → Data Source → + New Query), e.g. TOTAL_SALARY_QUERY: SELECT SUM(SAL) AS TOTAL FROM EMP.
  2. Drag KPI Card from the Palette onto the Report Header or Footer. (Enterprise plan feature — an Administrator can grant it per-user under Administration → Users → Permissions.)
  3. Properties panel: Data source → TOTAL_SALARY_QUERY; Aggregate → SUM; Measure field → SAL; Label → "Total Salary"; Number format → 999,999.00.
  4. Add several KPI Cards, each with its own Data source, to build a real multi-metric dashboard on one report.

Dashboard reports (full-screen, auto-refresh)

  1. Select the report itself → Report type → Dashboard.
  2. Build the layout with several KPI Card/Chart/Crosstab elements, each pointed at its own named query.
  3. Preview auto-fits the report to fill the available space (not a fixed paper size) and offers a Full Screen button for a true full-browser-viewport wallboard view.
  4. For an actual kiosk deployment, link the report as HTML with ?refresh=<seconds> appended:
    http://your-server:4000/api/reports/<report-id>/render?format=html&apiKey=<key>&refresh=60
Full reference

These same walkthroughs, plus a quick-reference table for every other component (Chart, Crosstab, List, Map, Barcode, Subreport, Conditional Formats, Style Templates), live in docs/USER_GUIDE.md inside your installation.

Oracle APEX integration

ApexReporter Studio runs as its own service alongside your Oracle APEX/ORDS mid-tier — there's no plug-in to install into APEX itself. An APEX page calls it over plain HTTPS, the same way it would call any external REST API, and the two systems can point at the same Oracle database without sharing an application server.

This section covers the setup checklist and the three calling patterns; for format-specific walkthroughs with runnable examples, see the PDF, Excel, scheduled, email, and invoice reporting guides, or the broader Oracle APEX reporting guide and report server architecture pages.

Three ways to invoke a report from APEX

ApproachJavaScript needed?Best for
Plain link / Redirect to URLNoA simple "Print" or "Download" button
JavaScript clientOne line, via a Dynamic ActionAnything client-facing — keeps the API key out of the browser's address bar
Embedded live previewYesShowing a report inline inside an APEX page or region, in an iframe

Setup checklist (do these in order)

  1. Register the JavaScript client first. Shared Components → User Interface → JavaScript → File URLs (application-level, so every page has it), and add the exact URL your own server serves it at, e.g.:
    http://reporter-host:4000/apexreporter-client.js or
                   
    https://apex-reporter.com/studio/apexreporter-client.js
    This must load as a real external <script src> — not pasted inline into "Execute when Page Loads" — so it exists before any button's Dynamic Action runs. Skipping or mistyping this step is the #1 cause of the ApexReporter is not defined error below.
  2. Design and save the report in ApexReporter Studio; copy its report id from the Open dialog (a UUID, e.g. eabe5c46-ace5-49fc-9bb8-0e4dd8c8db07).
  3. Make sure the report's query uses named binds that match a Parameter defined on the report (e.g. :P_DEPTNO in the SQL ↔ a Parameter named P_DEPTNO).
  4. Set a service-caller API key ([security] report_api_key= in config.ini, or REPORT_API_KEY) — APEX-driven calls have no interactive session of their own, so this key is what authenticates them; every call gets 401 without it.
  5. Set allowed origins (CORS) to your APEX host — [security] cors_origin=https://your-apex-host.example.com — since the browser is calling a different origin than the one serving the APEX page. Restart the server after changing this.

Example — running a report from a button click

Report saved with id eabe5c46-ace5-49fc-9bb8-0e4dd8c8db07, ApexReporter running at http://reporter-host:4000, a page item P1_DEPTNO already on the page. Dynamic Action on the button's Click event → Execute JavaScript Code:

ApexReporter.run({
  baseUrl: "http://reporter-host:4000",
  report: "eabe5c46-ace5-49fc-9bb8-0e4dd8c8db07",
  format: "pdf",
  parameters: { P_DEPTNO: $v("P1_DEPTNO") },
  target: "_blank",
  apiKey: "your-report-api-key"
});

$v("P1_DEPTNO") reads a page item's current value with no page submit required; any number of parameters can be passed as long as each one matches a Parameter defined on the report. format also accepts xlsx, csv, docx, pptx, html, or json; target accepts "_blank", "_self", or "download" to force a file download instead of navigating.

Example — embedding a live preview inline

Add a Static Content region containing <iframe id="reportPreviewFrame" style="width:100%; height:800px; border:0"></iframe>, then a Dynamic Action (page load, button click, or a page item's Change event for a live-filter feel):

ApexReporter.preview("#reportPreviewFrame", {
  baseUrl: "http://reporter-host:4000",
  report: "eabe5c46-ace5-49fc-9bb8-0e4dd8c8db07",
  parameters: { P_DEPTNO: $v("P1_DEPTNO") }
});

This always renders format=html and just points the iframe's src at the render URL. Since an iframe can't send a custom header, an API key here must be appended to the URL as &apiKey=... instead — build the URL with ApexReporter.buildUrl(baseUrl, report, "html", parameters) + "&apiKey=" + key, or keep this endpoint behind network-level access control (VPN/firewall) if you'd rather not expose the key in markup.

Example — plain link, zero JavaScript

An APEX button set to Action → Redirect to URL, using APEX's own &ITEM_NAME. substitution syntax, works with no script at all:

http://reporter-host:4000/api/reports/eabe5c46-ace5-49fc-9bb8-0e4dd8c8db07/render?format=pdf&apiKey=your-report-api-key&P_DEPTNO=&P1_DEPTNO.

APEX resolves &P1_DEPTNO. to that page item's current value before redirecting. Since the key is visible in the URL/browser history this way, prefer the JavaScript client above whenever the report is reachable from an untrusted network.

Row-level actions in Interactive Reports/Grids

Add a "Print this row" link or button column that either targets the plain-link URL with the row's key substituted via APEX's column-link syntax (#DEPTNO#), or runs a Dynamic Action that calls the JavaScript client with the clicked row's value.

Fixing "ApexReporter is not defined"

This means the browser never loaded apexreporter-client.js before your button's code ran. Fix, in order:

  1. Open DevTools → Network, reload the page, and confirm a request for apexreporter-client.js returns 200 — not 404 (wrong host/port in the File URL) or a connection/CORS error (server unreachable or not running).
  2. Confirm the script is registered as a File URL (Shared Components → JavaScript), not pasted as inline code — an external <script src> is what makes it available before Dynamic Actions fire.
  3. If the script loads fine (step 1 passes) but ApexReporter.run(...) still throws or silently fails, that's a separate CORS problem, not this error — recheck the cors_origin setup step above.
  4. For a button inside an Interactive Report/Grid column, make sure the Dynamic Action survives the region's own AJAX refresh (bind it so it fires on the refreshed DOM, not only at initial page load).

Plug-ins & migration

Five optional plug-ins ship with every installation, already installed but locked until activated. Each is a one-time, per-installation purchase — $1,249, lifetime license — independent of your Basic/Pro/Enterprise plan, and it never expires. For invoice/statement-specific migration guidance once a report is imported, see the invoice reporting guide.

Oracle Reports Migrator — $1,249

Converts an Oracle Reports Builder 12c report definition (SQL, groups, layout, and PL/SQL) into a starting ApexReporter report.

JasperReports Migrator — $1,249

Converts a JasperReports (.jrxml) report definition — fields, groups, SQL, and layout — into a starting ApexReporter report.

JasperReports XML Export — $1,249

Exports any report built in the designer back out as a JasperReports-compatible .jrxml file — the reverse direction of the Migrator above, for teams standardizing on Jaspersoft Studio downstream. Also available as a per-key feature override on the whole-app license itself for Enterprise customers who'd rather bundle it into their plan key.

Custom DB Host — $1,249

Every database connection is locked to localhost by default on every plan, including Enterprise. This plug-in is the only way to point a connection at a different host — for deployments where the Studio server and the target database live on separate machines. Deliberately never granted by the whole-app license key or any plan tier; it always requires this dedicated key.

Alternate DB Engines — $1,249

Every connection is Oracle, CSV, or JSON by default on every plan, including Enterprise. This plug-in is the only way to also connect to PostgreSQL or MySQL. Deliberately never granted by the whole-app license key or any plan tier — unlike JasperReports XML Export above, it has no per-key override path either; it always requires this dedicated key.

Activating a plug-in

  1. Open Administration → Plug-ins from the toolbar. Every plug-in is listed as "Installed" but "Not activated" until a key is entered.
  2. Paste the activation key issued for that plug-in and click Activate.
  3. Once activated, the matching feature (an import/export toolbar button, or a connection's Host field) is enabled for the whole installation — it stays activated across restarts, not per-user, unless an Administrator has restricted a specific user's access to it (see Users & roles below).

Uninstalling a plug-in

An Administrator can revoke a previously-activated plug-in at any time from the same panel — click Uninstall. This clears the activation immediately across the whole installation; using it again later requires entering the activation key again.

Hardware-locked, like the main license key

A plug-in activation key can be issued tied to this machine's hardware fingerprint (the same value shown in the About panel for the main license), so a key can't simply be copied to a second installation. Give your hardware key to whoever issues the plug-in key if you need a hardware-locked one; a floating key works on any machine.

Creating a migratable export from Oracle Reports Builder 12c

The importer needs the report's definition as XML, not the data output a running report produces. Two ways to get it:

Method 1: Using the Oracle Reports Builder (GUI)

This is the easiest method if you prefer a visual interface and only have a few files to convert.

  1. Open Oracle Reports Builder 12c.
  2. Click File in the top menu.
  3. Select Open and choose your .rdf file.
  4. Click File again.
  5. Select Save As.
  6. Click the File Type dropdown menu.
  7. Select Reports XML (*.xml).
  8. Click Save.

Method 2: Using the Command Line Utility (rwconverter)

This is the fastest method for batch conversions or automation scripts. Oracle provides the rwconverter executable inside your middleware home directory.

  1. Open your command prompt (Windows Terminal or Linux Shell).
  2. Navigate to your Oracle Forms/Reports binary directory where rwconverter is located. For example:
    Windows: C:\Oracle\Middleware\Oracle_Home\user_projects\domains\base_domain\developer_common\bin\
    Linux:   /u01/app/oracle/middleware/user_projects/domains/base_domain/developer_common/bin/
  3. Run the conversion command using the syntax below:
    rwconverter userid=username/password@database source=input_file.rdf dest=output_file.xml stype=rdffile dtype=xmlfile batch=yes
Not the same as DESFORMAT=XML

Running a report with DESFORMAT=XML produces the report's row data output for that one execution — not its design. The importer needs the Builder's own XML save/export of the report definition itself, produced by either method above.

Creating a migratable export from Jaspersoft Studio

.jrxml is Jaspersoft Studio's native, plain-text save format — every report you design in it already exists as a .jrxml file on disk, so there's no separate export step. Locate that file (or use File → Save if you haven't yet) and hand it to the importer as-is.

Importing into ApexReporter Studio

  1. In the toolbar, click Import Oracle Reports Structure (XML) or Import JasperReports (JRXML) — enabled once the matching plug-in above is activated.
  2. Choose the .xml or .jrxml file. The importer parses it and shows a summary — report style, parameter/group/column/summary counts, and how many bands it produced.
  3. Review anything listed under "needs manual review" — text this specific importer couldn't confidently translate. For an Oracle Reports import, the original PL/SQL for any such item can be viewed inline via "Show original PL/SQL" before you decide how to reproduce it.
  4. Click Import into Designer. The report opens in the designer exactly like any other — attach a real Data Source connection before previewing, since the SQL is imported but no connection is attached automatically.
Nothing is silently dropped

Custom PL/SQL formulas/placeholders (Oracle Reports) and Groovy/Java expressions, scriptlets, or crosstabs (JasperReports) are left in place and flagged for manual review rather than guessed at or discarded — matching this project's rule of never inventing business logic it can't verify.

Management

Report lifecycle

Reports are created from a blank canvas, from a guided wizard that scaffolds a layout from your chosen columns, or by migrating an existing Oracle Reports or JasperReports definition via the plug-ins above. Every save is versioned; folders and tags help organize a larger catalog, filterable in the Open dialog.

The Open dialog itself supports selecting multiple reports at once — a checkbox per row plus Select all — the same way a native OS file-open dialog does, for bulk Delete (skipping and reporting any you don't have permission to delete) and, when the whole selection is your own reports, bulk Move to one destination folder.

Connections

Connection profiles are created, tested, and managed from the Connections panel — name, EZConnect string or TNS alias, and credentials, with a one-click connection test before you rely on it in a report.

Every connection is Private by default — visible only to its owner and anyone it's explicitly shared with. An Administrator can instead mark a connection Public, making it visible to and usable by every signed-in user regardless of ownership or sharing; only an Administrator can set or change this, and it never changes who can edit, delete, or manage sharing on the connection. Separately, an Administrator can restrict which users are allowed to create new connections at all (see Feature overrides below) — someone denied that permission can still use any connection already shared with them or made Public.

Scheduled jobs

The Scheduled Reports panel lists every job with its cron schedule, delivery target, enabled state, last run time, and last status, and lets you drill into a job's full run history — including retries and error detail on a failed attempt.

Fonts & plug-ins

Custom font families are uploaded and managed from the Fonts panel. The Oracle Reports and JasperReports migration importers are activated the same way — see Plug-ins & migration above for the full walkthrough.

Administration

Every administrative feature lives in one Administration window, opened from its own toolbar button, with a separate tab for each area: Preferences, Shortcuts, Plug-ins, Users, Administration, Sessions, Visitor Inbox, and Email & FTP. The toolbar button itself is visible to every signed-in role — not just Administrator/Designer/Developer — and the Preferences, Shortcuts, and Plug-ins tabs are open to whoever opens it: Preferences holds each user's personal interface settings (light/dark, typeface, size, accent) and new-element style defaults, described under Personalisation above, and Shortcuts holds their personal keyboard-shortcut remapping (see Selection, alignment & keyboard shortcuts above). The other five tabs are Administrator-only, so anyone without that role opening this window sees just Preferences, Shortcuts, and Plug-ins.

Users & roles

Administrators manage accounts and role assignments from the Users tab. Six roles are built in, but they work on two different levels: what you can do in the application, and which named audience a specific report is restricted to.

Platform access

Every route in the application checks a role against exactly one of two effective tiers — there is no functional difference within either group:

RoleWhat it's for
AdministratorEverything: full authoring, plus user/role management, per-user permissions, the audit log, the Administration dashboard, and the Visitor Inbox.
DesignerFull authoring access — identical to Developer below. Intended as a label for report-layout/design-focused authors, if your organization wants to track that distinction; the application itself doesn't enforce any difference between the two.
DeveloperFull authoring access — identical to Designer above. Intended as a label for PL/SQL/query-focused authors, for the same organizational reason.
PublisherRead-only: list, open, run, and export reports — no authoring. Functionally identical to Runtime User and Viewer below; exists as a distinct name for the audience-restriction use case described next.
Runtime UserRead-only, identical to Publisher and Viewer — a label for accounts that only ever execute already-built reports (e.g. an automated caller or a scheduled-report recipient acting as a named user).
ViewerRead-only, identical to Publisher and Runtime User — a label for accounts that browse and open reports but never run anything unattended.

Per-report audience restriction

This is where having six distinct names actually matters: any report can be restricted to specific roles via its access-control setting, independent of the platform-access tiers above. An author could mark a sensitive report visible only to "Publisher," for example, even though Publisher, Runtime User, and Viewer all grant identical baseline access to the application otherwise — the six role names exist to give report authors meaningful audience labels for this restriction, not because the platform treats each of the six differently on its own. Leaving a report unrestricted (the default) makes it open to any signed-in user.

The built-in admin account is a permanent break-glass superuser: it always holds every role, can't be deactivated or given an expiry, and its password can only be changed by itself or via config.ini — so a deployment can never be accidentally locked out of its own administration.

Finding & duplicating users

The Users tab has a search box that filters the account list by username or display name as you type — useful once a deployment has more than a handful of accounts. Each row also has a Duplicate button: it pre-fills the New User form with the source account's exact role assignment, so you only need to enter a new username and password. Once the new account is created, every other privilege the source account has is copied over too — its per-user feature overrides, connection-count cap, and plug-in access (see Per-user permissions below) — giving you a genuine "same roles and privileges" clone rather than just a same-role account you'd still have to configure by hand.

Backing up & restoring users and reports

Four buttons next to the search box turn the Users tab into a real backup/restore tool, not just an audit view:

  • Export Users downloads a CSV with one row per account and one column per "right": username, display name, email, active/locked state, failed-login count, created/expiry dates, role assignment, every per-user override from the Permissions panel (connection-cap override, each feature's Allow/Deny/Inherit, each plug-in's Allow/Deny/Inherit) — and the account's actual password hash. Never a plaintext password (this app never stores one) — but real enough that a restored account logs in with its original password, so treat a downloaded copy of this file exactly like a password database.
  • Export Reports downloads a companion CSV — one row per report and rights-holder (an Owner row plus one per explicit Editor/Viewer share for a personal report; a single Team row showing the role restriction instead for a legacy/team report) — plus each report's full design (every band and element) inline on its first row, so the file is a genuine backup, not just a rights list.
  • Import Users reads that same file back and makes every account in it match: an existing username (matched case-insensitively; the built-in admin is always left alone) has its roles, active state, expiry, password, and overrides overwritten to match the row — a real restore, not a merge, which is why it asks for confirmation first. A row with no password hash (an older export, or one edited by hand) still creates the account, with a random password generated and shown once in the results for you to hand out.
  • Import Reports recreates any report in the file that doesn't already exist here — same id, same content, same original creation date — with its owner and shares resolved by username against accounts that exist on this install. Run Import Users first if you're rebuilding from scratch: an owner or share recipient that doesn't exist yet just falls back to a Team report (or skips that one share) with a warning, rather than failing the whole import. A report whose id already exists is left completely untouched, never overwritten.

Together, exporting both files and re-importing them (in that order) is the "little effort, full restore" path for rebuilding a deployment — no report content needs to be rebuilt by hand, and nobody needs a password reset.

Account expiry & lockout

Any account other than admin can be given an expiry date/time — past that point it can no longer log in, and an already-open session is closed immediately rather than waiting for it to expire naturally. After five consecutive failed login attempts, an account locks automatically and needs an Administrator to unlock it from the Users tab; the built-in admin account is permanently exempt from lockout.

Per-user permissions

Beyond role assignment, an Administrator can fine-tune exactly what one specific user can do — independent of, and layered on top of, the installation's plan/license. Click the permissions icon on any user's row to set:

  • Feature overrides — force any individual feature (report import/export, version history, personal folders, scheduled reports, custom fonts, JasperReports XML export, creating new database connections, and more) to Allow or Deny for that one user, regardless of what the plan otherwise includes. Left on "Inherit," the user simply follows the plan/license default like everyone else.
  • Connection limit — override the plan's whole-install connection cap with a personal limit for one user, e.g. letting a power user like "scott" create more connections than the plan would otherwise allow, while capping a more limited account lower.
  • Plug-in access — restrict a specific user to only certain activated plug-ins, e.g. allowing the JasperReports importer but not the Oracle Reports importer for one particular account, even though both are activated for everyone else on the installation.

Every override is enforced server-side, not just hidden in the interface — a denied user can't work around it by calling the underlying action directly.

Audit log

Every meaningful action — logins, and every create, update, or delete of a report, connection, user, or schedule — is written to a permanent audit trail, reviewable by an Administrator at any time.

Administration dashboard

The Administration tab surfaces user, report, connection, and schedule counts, connections broken down by type, scheduled-job health (success/failure/running over a trailing window), and the audit log — everything an administrator needs to check the health of a deployment at a glance.

Sessions

The Sessions tab lists everyone currently signed in to the installation — one row per user (not per browser tab, so someone logged in from two devices at once still shows as a single row with a session count), with their last login time and when their session expires. An Administrator can end any user's session with one click, signing them out of every device/browser at once immediately; their very next action anywhere is treated exactly like an expired login, no restart or wait required. Ending your own session works the same way, for signing yourself out remotely.

Visitor Inbox

The public marketing site's Contact Us form and "forgot password" request both land here, not in an external inbox — each submission can be marked Unread, Read, Important, Needs Action, or Resolved as an Administrator works through it, with an unread-count badge on the toolbar so nothing sits unnoticed.

Messages are archived automatically once they are older than [inbox] archive_after_days in config.ini (default 30; 0 disables it; checked at startup and every 6 hours) or by hand with a row's Archive button, and archived messages drop out of the unread count. The Archive view can restore a message, delete it, delete every archived message older than N days, or delete all archived — and only archived messages can be deleted, so nothing is removed without first leaving the active inbox.

A contact message whose Subject is exactly "Request Access" — the Studio login screen's own Request Access button prefills this — gets two extra one-click actions when expanded: Create User creates an account using the sender's email as both username and email, with a deterministic initial password (the email's local part, first letter capitalized, plus @1234$ — e.g. abc@xyz.com → Abc@1234$); Send Welcome Email emails that same username/password with a short welcome message via the configured SMTP settings. The two can be clicked in either order — the password is computed the same way both times — but Send Welcome Email requires the account to already exist.

Email & FTP

The SMTP account and FTP/SFTP target used by every scheduled report job's Email or FTP/SFTP delivery (see Scheduled jobs under Management above) can be viewed and changed from this tab, instead of only through config.ini's [smtp] and [delivery] sections. A Send Test Email button sends a real message through the current settings — to a given address, or the signed-in Administrator's own account email by default — so a configuration can actually be confirmed working, not just entered and hoped for.

Takes effect immediately, resets on restart

Same convention as the AI provider settings on the Administration tab: a change here applies to the very next send with no restart needed, but it's never written back to config.ini — a password typed into this tab is never sent back to the browser either. Restarting the server reverts both Email and FTP/SFTP settings to whatever config.ini (or the environment) still say, exactly the way every other config.ini-backed setting already behaves.

"Use TLS" unchecked means no TLS at all

With Use TLS off, no encryption is attempted with the SMTP server whatsoever — not even an opportunistic STARTTLS upgrade. This matters for a local mail relay on the same machine (e.g. Postfix/sendmail reachable via the Linux mail command): that command never negotiates TLS at all, but a network SMTP client that does attempt STARTTLS will fail against a relay's expired or self-signed certificate, even though plain local delivery works fine. If email suddenly fails with a certificate error after saving here, leave Use TLS unchecked for a local/loopback relay, or renew the relay's certificate if you specifically need TLS.

Security & deployment

  • Every action requires a signed-in session, or the dedicated trusted-service-caller key for headless integrations — there is no open-by-default mode.
  • Connection passwords are encrypted at rest, never returned to the browser once saved.
  • Session cookies are HTTP-only and same-site restricted.
  • Put the application behind HTTPS via a reverse proxy in front of it — the application itself expects TLS to be terminated there.
  • Restrict allowed browser origins (CORS) to the exact hosts that need to call it, rather than leaving it open.
  • Review role assignments periodically — anyone with Designer, Developer, or Administrator access can create and test Oracle connections using whatever credentials they submit.
  • Check the audit log periodically for unexpected activity.

Public form abuse protection

The two endpoints that don't require a session — the website's Contact Us form and "forgot password" request — are unauthenticated by necessity (that's the point: a prospect or a locked-out user has no account yet). Three layers guard against spam/bulk-submission abuse, all server-side (bypassing the website's own form and posting directly to the API doesn't get around any of them):

  • A honeypot field plus a minimum-time-since-page-load check — a script that posts immediately, or fills every field including the one real visitors never see, is treated as a bot and gets a fake success response with nothing actually stored (so it has no error signal to adapt against).
  • A persisted, three-way submission throttle (per-IP, per-email, and a global ceiling across all senders) — survives a server restart, unlike a purely in-memory counter, so it can't be reset by triggering one.
  • Creating a real user account from a "Request Access" message is never automatic — an Administrator must click Create User in the Visitor Inbox for each one, so flooding the inbox with fake requests can't mint accounts by itself.
Not a substitute for a CAPTCHA against a determined attacker

These are pragmatic, dependency-free deterrents against casual/scripted spam, not a hard security boundary — a sophisticated, IP-rotating, human-timed submitter can still get messages through at a trickle. If spam becomes an operational problem, front the site with a real CAPTCHA (hCaptcha/Turnstile) or add email verification before a Request Access message becomes actionable.

Data persistence & backup

All application state — the metadata database, saved report versions, and uploaded assets — lives under one configured data directory. Point that directory at a persistent, backed-up volume in any real deployment; the Oracle databases you report against are, of course, backed up independently by your own database team.

Every installer package ships backup-data/restore-data (.ps1 and .sh) alongside start-runtime/stop-runtime, which back up (or restore) that whole data directory in one versioned archive under backups/. That single directory holds essentially everything an Administrator can see or change in the Studio app itself — every user's personal reports and folders, team reports, connections, users (including each one's personal preferences and keyboard-shortcut remaps), schedules, plug-in activation state, the Visitor Inbox, license state, and — since it's saved to the same database, not left in server memory — Email/FTP delivery settings changed from Administration → Email & FTP. Both scripts refuse to run while the runtime still appears to be listening (copying/restoring a live SQLite file can corrupt it), and restore-data takes its own safety backup of whatever's currently there before overwriting it, so a restore is itself undoable.

Deliberately not backed up

The AI provider settings (Administration → Administration tab) — provider choice, API keys, model — are the one Administration setting that's intentionally never written to disk at all, sensitive-credential-style, same as they're never written back to config.ini; they reset to whatever config.ini/the environment say on every restart, and a backup/restore has nothing to capture there.

Troubleshooting & FAQ

Can I try ApexReporter Studio before buying a plan?

Yes, two ways. A live hosted demo is available anytime at apex-reporter.com/studio — no install, no signup, sample data only. Or download the free trial installer and run it on your own Windows or Linux server against your own Oracle instance (no license key, capped at 5 reports and 1 connection — see Trial installer above). When you're ready for your own connections, users, and schedules without those caps, install it under a Basic, Pro, Enterprise, or Custom plan.

Is this a cloud service?

No — ApexReporter Studio is self-hosted. It installs on your own Windows or Linux server and connects directly to your Oracle instance; your report data and query results never leave your network.

Do we need Oracle Instant Client?

No. Standard username/password and EZConnect/TNS connections run in thin mode out of the box.

Can we migrate existing Oracle Reports or JasperReports definitions?

Yes, via the Oracle Reports Migrator and JasperReports Migrator plug-ins (one-time purchase per installation — see Plug-ins & migration). Once activated, each reads a report definition export and converts it into a starting report, flagging anything that needs manual review rather than guessing at business logic.

The application won't start

Check the startup console output first — it states plainly whether the issue is a port already in use, an unmet Node.js version requirement, or a license activation key that's configured but doesn't verify, rather than failing silently. (A blank activation key isn't a startup failure — the app starts locked and prompts for one on screen instead; see Licensing & plans.)

A scheduled job keeps failing

Open the job's run history in the Scheduled Reports panel — every attempt (including retries) records its actual error, which is almost always a query error, an expired connection credential, or a misconfigured delivery target.

PDF export still doesn't match Preview/Print after setting pdf_engine=chromium

The headless browser isn't downloaded automatically — it's a deliberate one-time manual step per machine (see PDF rendering engine above), so if it was skipped, every render silently falls back to pdfmake and looks unchanged. Check the server log for a line like pdf_engine=chromium failed rendering "...", falling back to pdfmake: ..., which states exactly why. Run npx puppeteer browsers install chrome in the server/ folder on that server (it doesn't carry over between machines, but does survive later patches/updates — the browser lives in its own cache folder, untouched by replacing the app's code). On a fresh Linux VPS the browser may also need a handful of OS shared libraries it depends on (libnss3, libatk1.0-0, libgbm1, and similar) if the log shows a missing-library error rather than "Could not find Chrome". And if the app runs as a specific service user (e.g. a systemd User=), run the install command as that same user — the browser is cached per-OS-user, so installing it under a different login than the one actually running the server won't be found.

Support

For licensing questions, deployment assistance, or to report an issue, use the contact options on the main site's pricing section. Administrators can also find build/version information and support details from within the running application via the About panel, or at a glance on the login screen itself, which always shows the running version.