Skip to content

Erste Schritte mit PDF Oxide (Kotlin)

PDF Oxide ist die schnellste PDF-Bibliothek für die JVM mit integrierter Textextraktion — 0,8 ms im Mittel, 100 % Erfolgsquote bei 3.830 PDFs. Das Kotlin-Binding ist eine idiomatische, Android-taugliche Fassade über dem Java-Binding: Es ergänzt use { } auf den schließbaren Handles und wandelt Java-Optional<T>-Rückgaben in nullbare T? um. Eine Bibliothek zum Extrahieren, Erstellen und Bearbeiten von PDFs. MIT-lizenziert, aufgebaut auf einem Rust-Kern.

Installation

Füge das Kotlin-Binding zu deiner build.gradle.kts hinzu. Es zieht transitiv das Java-Binding mit ein, das die native JNI-Brücke verwaltet:

dependencies {
    implementation("fyi.oxide:pdf-oxide-kotlin:0.3.69")
}

Voraussetzungen: JDK 17+. Unter Android lieferst du die native libpdf_oxide_jni.so in jniLibs/<abi>/ aus; auf der Desktop-JVM findet der Loader sie automatisch (bei Bedarf mit -Dfyi.oxide.pdf.lib.path=<path> überschreiben).

Schnellstart

Erstelle ein PDF aus Markdown, öffne es und lies den Text wieder aus. Die Handles Pdf und PdfDocument sind AutoCloseable, also umschließt du sie mit use { }:

import fyi.oxide.pdf.Pdf
import fyi.oxide.pdf.PdfDocument
import fyi.oxide.pdf.producerOrNull

Pdf.fromMarkdown("# Hello pdf_oxide\n\nThis is a **Kotlin** binding.\n").use { pdf ->
    PdfDocument.open(pdf.save()).use { doc ->
        println("pages:    ${doc.pageCount()}")
        println("producer: ${doc.producerOrNull() ?: "(none)"}")
        println(doc.extractText(0))
    }
}

Pdf.fromMarkdown(String) liefert einen schließbaren Pdf-Builder; pdf.save() serialisiert ihn zu einem ByteArray. PdfDocument.open(ByteArray) öffnet dieses zum Lesen.

Ein PDF öffnen

Öffne ein vorhandenes Dokument aus Bytes und untersuche seine Metadaten. producerOrNull() und creatorOrNull() sind die nullbaren Kotlin-Sichten über die Java-Optional-Getter:

import fyi.oxide.pdf.PdfDocument
import fyi.oxide.pdf.producerOrNull
import fyi.oxide.pdf.creatorOrNull

PdfDocument.open(pdfBytes).use { doc ->
    println("open:     ${doc.isOpen}")
    println("pages:    ${doc.pageCount()}")
    println("producer: ${doc.producerOrNull() ?: "(none)"}")
    println("creator:  ${doc.creatorOrNull() ?: "(none)"}")
}

Textextraktion

Extrahiere reinen Text aus einer beliebigen Seite über ihren nullbasierten Index oder iteriere über jede Seite:

import fyi.oxide.pdf.PdfDocument

PdfDocument.open(pdfBytes).use { doc ->
    // eine einzelne Seite
    println(doc.extractText(0))

    // jede Seite
    for (i in 0 until doc.pageCount()) {
        println("--- Page ${i + 1} ---")
        println(doc.extractText(i))
    }
}

Seitenelemente

doc.page(i) liefert eine PdfPage, die strukturierte Geometrie offenlegt — Wörter, Zeilen, Zeichen, Tabellen, Bilder und Annotationen. Jedes Wort trägt seinen Text und ein Begrenzungsrechteck:

import fyi.oxide.pdf.PdfDocument

PdfDocument.open(pdfBytes).use { doc ->
    val page = doc.page(0)
    println("size: ${page.width()} x ${page.height()}")

    page.words().take(8).forEach { word ->
        println("${word.text()} @ ${word.bbox()}")
    }

    println("lines:       ${page.lines().size}")
    println("chars:       ${page.chars().size}")
    println("tables:      ${page.tables().size}")
    println("images:      ${page.images().size}")
    println("annotations: ${page.annotations().size}")
}

Das bbox() eines Worts ist eine BBox mit Hilfsmethoden wie width() und height().

Markdown- & HTML-Konvertierung

Konvertiere das gesamte Dokument nach Markdown oder rendere eine Seite als HTML:

import fyi.oxide.pdf.PdfDocument

PdfDocument.open(pdfBytes).use { doc ->
    val markdown = doc.toMarkdown()  // alle Seiten
    println(markdown)

    val html = doc.toHtml()
    println(html)
}

Suche

Suche nach Text im gesamten Dokument. Jeder Treffer legt seinen Text über text() offen:

import fyi.oxide.pdf.PdfDocument

PdfDocument.open(pdfBytes).use { doc ->
    val matches = doc.search("configuration")
    matches.forEach { m ->
        println("match: ${m.text()}")
    }
}

Automatische Extraktion

AutoExtractor führt die vollständige Extraktions-Pipeline in einem Aufruf aus und liefert ein AutoResult mit dem Text sowie optionalen Markdown-/HTML-Renderings zurück. Die Erweiterungen markdownOrNull() / htmlOrNull() wandeln die Java-Optional-Rückgaben in nullbare Werte um:

import fyi.oxide.pdf.PdfDocument
import fyi.oxide.pdf.AutoExtractor
import fyi.oxide.pdf.markdownOrNull
import fyi.oxide.pdf.htmlOrNull

PdfDocument.open(pdfBytes).use { doc ->
    val result = AutoExtractor.of(doc).extractDocument()
    println(result.text())
    result.markdownOrNull()?.let { println(it) }
    result.htmlOrNull()?.let { println(it) }
}

Bearbeiten

DocumentEditor öffnet ein PDF für strukturelle Änderungen — zum Beispiel das Entfernen von Metadaten vor dem Teilen — und serialisiert das Ergebnis anschließend wieder zu Bytes:

import fyi.oxide.pdf.DocumentEditor

DocumentEditor.open(pdfBytes).use { editor ->
    editor.scrubMetadata()
    val cleaned: ByteArray = editor.save()
    println("cleaned: ${cleaned.size} bytes")
}

Nächste Schritte