Primeiros passos com a PDF Oxide (Kotlin)
A PDF Oxide é a biblioteca PDF mais rápida para a JVM com extração de texto embutida — média de 0,8 ms e 100% de aprovação em 3.830 PDFs. O binding de Kotlin é uma fachada idiomática e pronta para Android sobre o binding de Java: ele adiciona use { } aos handles closable e converte os retornos Optional<T> do Java em T? nullable. Uma única biblioteca para extrair, criar e editar PDFs. Licença MIT, construída sobre um núcleo em Rust.
Instalação
Adicione o binding de Kotlin ao seu build.gradle.kts. Ele traz transitivamente o binding de Java, que é o dono da ponte nativa via JNI:
dependencies {
implementation("fyi.oxide:pdf-oxide-kotlin:0.3.69")
}
Requisitos: JDK 17 ou superior. No Android, distribua a biblioteca nativa libpdf_oxide_jni.so em jniLibs/<abi>/; na JVM de desktop o loader a encontra automaticamente (use -Dfyi.oxide.pdf.lib.path=<path> para sobrescrever quando necessário).
Início Rápido
Gere um PDF a partir de Markdown, abra-o e leia o texto de volta. Os handles Pdf e PdfDocument são AutoCloseable, então envolva-os em 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) retorna um builder Pdf closable; pdf.save() o serializa em um ByteArray. PdfDocument.open(ByteArray) abre esse conteúdo para leitura.
Abrindo um PDF
Abra um documento existente a partir de bytes e inspecione seus metadados. producerOrNull() e creatorOrNull() são as visões nullable de Kotlin sobre os getters Optional de Java:
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)"}")
}
Extração de texto
Extraia texto puro de qualquer página pelo seu índice (começando em zero) ou percorra todas as páginas:
import fyi.oxide.pdf.PdfDocument
PdfDocument.open(pdfBytes).use { doc ->
// uma única página
println(doc.extractText(0))
// todas as páginas
for (i in 0 until doc.pageCount()) {
println("--- Page ${i + 1} ---")
println(doc.extractText(i))
}
}
Elementos da página
doc.page(i) retorna um PdfPage que expõe a geometria estruturada — palavras, linhas, caracteres, tabelas, imagens e anotações. Cada palavra carrega seu texto e uma bounding box:
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}")
}
A bbox() de uma palavra é um BBox com helpers como width() e height().
Conversão para Markdown e HTML
Converta o documento inteiro para Markdown ou renderize uma página em HTML:
import fyi.oxide.pdf.PdfDocument
PdfDocument.open(pdfBytes).use { doc ->
val markdown = doc.toMarkdown() // todas as páginas
println(markdown)
val html = doc.toHtml()
println(html)
}
Busca
Busque por texto em todo o documento. Cada correspondência expõe seu texto via text():
import fyi.oxide.pdf.PdfDocument
PdfDocument.open(pdfBytes).use { doc ->
val matches = doc.search("configuration")
matches.forEach { m ->
println("match: ${m.text()}")
}
}
Extração automática
AutoExtractor roda o pipeline completo de extração em uma única chamada e retorna um AutoResult com o texto, além de renderizações opcionais em Markdown/HTML. As extensões markdownOrNull() / htmlOrNull() convertem os retornos Optional de Java em valores nullable:
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) }
}
Edição
DocumentEditor abre um PDF para edições estruturais — por exemplo, limpar os metadados antes de compartilhar — e então serializa o resultado de volta em bytes:
import fyi.oxide.pdf.DocumentEditor
DocumentEditor.open(pdfBytes).use { editor ->
editor.scrubMetadata()
val cleaned: ByteArray = editor.save()
println("cleaned: ${cleaned.size} bytes")
}
Próximos passos
- Primeiros passos com Java – o binding da JVM que a fachada de Kotlin encapsula
- Primeiros passos com Python – usando a PDF Oxide a partir de Python
- Extração de texto – opções e receitas detalhadas de extração
- Criação de PDF – criação avançada com builders, criptografia e metadados
- Edição – modificando PDFs existentes, anotações e campos de formulário