Skip to content

cmp-pdf-generator

cmp-pdf-generator

Cross-platform PDF generation library for Kotlin Multiplatform.

Status: Experimental. All public APIs marked @ExperimentalPdfGeneratorApi. Ships alongside the other cmp-* modules at the shared kmptoolkit.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 PdfError sealed 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-html and org.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.