Report definition registry and pure helper functions.
Provides the defreport macro for declaring report definitions as data,
an in-process registry backed by an atom, and pure transformation helpers
used by shell adapters.
FC/IS rule: no I/O here. All side effects (file writing, HTTP responses, calling :data-source) live in the shell layer.
Report definition registry and pure helper functions. Provides the `defreport` macro for declaring report definitions as data, an in-process registry backed by an atom, and pure transformation helpers used by shell adapters. FC/IS rule: no I/O here. All side effects (file writing, HTTP responses, calling :data-source) live in the shell layer.
Protocol definitions (interfaces) for the reports module.
All adapters (PDF, Excel) implement ReportGeneratorProtocol. This keeps the core layer decoupled from any specific rendering backend.
Protocol definitions (interfaces) for the reports module. All adapters (PDF, Excel) implement ReportGeneratorProtocol. This keeps the core layer decoupled from any specific rendering backend.
Malli validation schemas for the reports module.
Malli validation schemas for the reports module.
Excel generation adapter using docjure (Apache POI wrapper).
Builds one worksheet per entry in :sheets, or derives a single sheet from :sections when :sheets is not provided.
Usage: (def xl-gen (create-excel-generator)) (generate! xl-gen my-report-def data {}) ;; => {:bytes #bytes[...] :type :excel :filename "my-report.xlsx"}
Excel generation adapter using docjure (Apache POI wrapper).
Builds one worksheet per entry in :sheets, or derives a single sheet
from :sections when :sheets is not provided.
Usage:
(def xl-gen (create-excel-generator))
(generate! xl-gen my-report-def data {})
;; => {:bytes #bytes[...] :type :excel :filename "my-report.xlsx"}PDF generation adapter using OpenHTMLtoPDF.
Three-step pipeline:
Usage: (def pdf-gen (create-pdf-generator)) (generate! pdf-gen my-report-def data {}) ;; => {:bytes #bytes[...] :type :pdf :filename "my-report.pdf"}
PDF generation adapter using OpenHTMLtoPDF.
Three-step pipeline:
1. Render Hiccup → HTML string (via hiccup.core/html)
2. Inject default CSS from resources/boundary/reports/default.css
3. Pass HTML to PdfRendererBuilder → ByteArrayOutputStream → bytes
Usage:
(def pdf-gen (create-pdf-generator))
(generate! pdf-gen my-report-def data {})
;; => {:bytes #bytes[...] :type :pdf :filename "my-report.pdf"}Word (DOCX) generation adapter using Apache POI XWPF.
Apache POI is already on the classpath as a transitive dependency via docjure → poi-ooxml. No new Maven dependencies are needed.
Supports the same declarative :sections API as the Excel adapter. The :template key is PDF-only and is ignored here.
Usage: (def wd-gen (create-word-generator)) (generate! wd-gen my-report-def data {}) ;; => {:bytes #bytes[...] :type :word :filename "my-report.docx"}
Word (DOCX) generation adapter using Apache POI XWPF.
Apache POI is already on the classpath as a transitive dependency
via docjure → poi-ooxml. No new Maven dependencies are needed.
Supports the same declarative :sections API as the Excel adapter.
The :template key is PDF-only and is ignored here.
Usage:
(def wd-gen (create-word-generator))
(generate! wd-gen my-report-def data {})
;; => {:bytes #bytes[...] :type :word :filename "my-report.docx"}Optional integration with boundary-jobs for async report generation.
This namespace provides async report generation via the jobs module. The jobs module is an OPTIONAL dependency — add it to your deps.edn:
{:deps {org.boundary-app/boundary-jobs {:mvn/version "0.1.0"}}}
If the jobs module is not available, async functions will throw descriptive errors with :type :missing-dependency.
Usage: ;; Queue report for async generation (queue-report-job! report-def {:invoice-id 42})
;; Register report job handler with jobs module (register-report-job-handler! job-registry)
The job handler will:
Optional integration with boundary-jobs for async report generation.
This namespace provides async report generation via the jobs module.
The jobs module is an OPTIONAL dependency — add it to your deps.edn:
{:deps {org.boundary-app/boundary-jobs {:mvn/version "0.1.0"}}}
If the jobs module is not available, async functions will throw descriptive
errors with :type :missing-dependency.
Usage:
;; Queue report for async generation
(queue-report-job! report-def {:invoice-id 42})
;; Register report job handler with jobs module
(register-report-job-handler! job-registry)
The job handler will:
- Resolve data via :data-source (if defined)
- Generate the report bytes
- Optionally store via boundary-storage (:storage-key in opts)
- Optionally send an email notification (:notify-email in opts)Public convenience API for report generation.
Provides generate (sync) and generate-async (queued via boundary-jobs).
These functions live in the shell layer — not core — because they
instantiate adapter records and call :data-source, both of which are
side effects (FC/IS: Core → Shell is forbidden).
Typical HTTP handler usage:
(require '[boundary.reports.shell.service :as reports])
(defn export-handler [request] (let [output (reports/generate invoice-report {:invoice-id 42})] {:status 200 :headers {"Content-Type" "application/pdf" "Content-Disposition" (str "attachment; filename="" (:filename output) """)} :body (java.io.ByteArrayInputStream. (:bytes output))}))
Public convenience API for report generation.
Provides `generate` (sync) and `generate-async` (queued via boundary-jobs).
These functions live in the shell layer — not core — because they
instantiate adapter records and call :data-source, both of which are
side effects (FC/IS: Core → Shell is forbidden).
Typical HTTP handler usage:
(require '[boundary.reports.shell.service :as reports])
(defn export-handler [request]
(let [output (reports/generate invoice-report {:invoice-id 42})]
{:status 200
:headers {"Content-Type" "application/pdf"
"Content-Disposition" (str "attachment; filename=\""
(:filename output) "\"")}
:body (java.io.ByteArrayInputStream. (:bytes output))}))cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |