cmp-pdf-generator¶
cmp-pdf-generator¶
Cross-platform PDF generation library for Kotlin Multiplatform.
Status: Experimental. All public APIs marked
@ExperimentalPdfGeneratorApi. Ships alongside the othercmp-*modules at the sharedkmptoolkit.version.
Features¶
- Input modes: HTML string, Markdown, Composable snapshot, programmatic DSL, image
- Output destinations: File, ByteArray, platform URI, Share intent, Print dialog, Save dialog
- Page configuration: A3/A4/A5/B5/Letter/Legal/Tabloid/Statement/Custom + portrait/landscape + per-edge margins + page numbers + headers/footers
- Branding: injectable logo + theme colors + typography + powered-by footer (fully de-branded base; mifos defaults available via
PdfBranding.mifosDefault()) - Pre-built templates: Invoice, Report, Receipt, Statement, Letter
- Error handling: typed
PdfErrorsealed hierarchy + cancellation +Flow<PdfProgressEvent>progress
Platform support¶
| Platform | HTML route | DSL route | Notes |
|---|---|---|---|
| Android | WebView + PrintManager | android.graphics.pdf.PdfDocument |
Min SDK from kmp-toolkit policy |
| JVM (Desktop) | OpenHTMLToPDF | Apache PDFBox direct | ~10MB transitive |
| iOS | WKWebView.createPDF |
PDFKit |
iOS 14+ |
| macOS | WKWebView.createPDF |
PDFKit |
macOS 11+ |
| JS (Browser+Node) | iframe + window.print() |
pdf-lib (npm) |
Browser: needs user gesture for print |
| wasmJs (Browser+Node) | iframe + window.print() |
Deferred (pdf-lib wasmJs interop pending) | HTML route only in v1; needs kotlinx-browser dep |
Not targeted: tvOS, watchOS, Linux native, mingwX64, wasmWasi. Per the Kotlin Multiplatform target tiers, these are Tier-2 / Tier-3 native targets.
kotlinx-htmlandorg.intellij.markdown— our HTML compiler + Markdown adapter dependencies — don't publish artifacts there. Adding them later requires upstream library coverage first.
Install¶
// build.gradle.kts (your consumer app)
dependencies {
val kmptoolkit = "3.2.8" // or latest — see https://central.sonatype.com/artifact/io.github.mobilebytelabs/cmp-pdf-generator
implementation("io.github.mobilebytelabs:cmp-pdf-generator:$kmptoolkit")
}
Quick start¶
HTML route¶
val generator = rememberPdfGenerator()
val html = "<h1>Hello</h1><p>World</p>"
val config = PageConfig(size = PageSize.A4, orientation = Orientation.PORTRAIT)
generator.generateAndSharePdf(html, fileName = "hello", pageConfig = config)
DSL route¶
val document = pdf {
pageConfig(PageConfig(size = PageSize.A4, margins = EdgeMargins.uniform(20)))
branding(PdfBranding.none())
page {
heading(level = 1, "Invoice")
text("Bill to: Acme Corp")
table {
row { cell("Item"); cell("Qty"); cell("Total") }
row { cell("Widget"); cell("3"); cell("$30") }
}
}
}
val result: PdfResult = generator.generate(document, PdfOutput.ByteArrayOutput)
Pre-built template¶
val invoice = InvoiceTemplate(
branding = PdfBranding.none(),
invoice = InvoiceData(/* ... */),
)
generator.generate(invoice.toDocument(), PdfOutput.Share)
Docs¶
- SPEC — full design intent
- API — every public symbol
- ADRs — engine choices, branding model, error model, target tiers, DSL shape
- Cookbook — invoice, receipt, report, image, composable-snapshot recipes
- Migration from mifos-x
License¶
Apache 2.0 — see LICENSE.
Module reference¶
Module Identity (auto-gen)
| Artifact | Package | Current version | Maven | Since | API tier |
|---|---|---|---|---|---|
io.github.mobilebytelabs:cmp-pdf-generator |
com.mobilebytelabs.kmptoolkit.pdf.generator |
UNKNOWN |
Central | 2026-05-30 | experimental |
Module purpose (one paragraph):
§2 Per-Platform Parity Matrix (auto-gen)¶
| Target | Source-set present | Real impl | UnsupportedPlatform stub | .kt count | Last reviewed | Coverage | Notes |
|---|---|---|---|---|---|---|---|
| androidMain | ✅ | ✅ real | 0 | 3 | 2026-06-01 | (legacy:full) | — |
| iosMain | ✅ | ✅ real | 0 | 1 | 2026-06-01 | (legacy:full) | — |
| macosMain | ✅ | ✅ real | 0 | 1 | 2026-06-01 | (legacy:full) | — |
| jvmMain | ✅ | ✅ real | 0 | 2 | 2026-06-01 | (legacy:full) | — |
| jsMain | ✅ | ✅ real | 0 | 3 | 2026-06-01 | (legacy:full) | — |
| wasmJsMain | ✅ | ✅ real | 0 | 1 | 2026-06-01 | (legacy:full) | — |
Legend (Real impl): ✅ real impl, 🟡 partial / wontfix-OS / wontfix-infra / legacy stub, ⛔ not declared, — N/A.
Legend (Coverage enum, since 2026-06-01): full (all public-API methods backed by OS primitive) · partial (most real; some typed UnsupportedPlatform fallbacks for contracts that don't apply) · wontfix-OS (OS lacks the primitive) · wontfix-infra (impl possible but CI/toolchain blocks it) · (legacy:full|stub) (auto-derived; pre-opt-in modules — add a // LD-2-coverage: {enum} comment to the platform's primary .kt file to graduate). See RULE-LIB-DEVELOPMENT-MD-001 LD-2 + ADRs for accepted wontfix cases.
API reference¶
Each release ships the module's full Dokka HTML site inside its
-javadoc.jar artifact on Maven Central.
In IntelliJ / Android Studio the IDE mounts the jar and surfaces it automatically in hover popups, Quick Documentation, and Symbol search.