Начало работы с PDF Oxide (Kotlin)
PDF Oxide — самая быстрая PDF-библиотека для JVM со встроенным извлечением текста: в среднем 0,8 мс и 100 % успешных тестов на 3830 PDF. Привязка для Kotlin — это идиоматичный, готовый для Android фасад над привязкой для Java: она добавляет use { } к закрываемым ресурсам и превращает Java-возвраты Optional<T> в nullable-тип T?. Одна библиотека для извлечения, создания и редактирования PDF. Лицензия MIT, в основе — ядро на Rust.
Установка
Добавьте привязку для Kotlin в ваш build.gradle.kts. Она транзитивно подтягивает привязку для Java, которая владеет нативным мостом JNI:
dependencies {
implementation("fyi.oxide:pdf-oxide-kotlin:0.3.69")
}
Требования: JDK 17+. На Android поставляйте нативную библиотеку libpdf_oxide_jni.so в jniLibs/<abi>/; на десктопной JVM загрузчик находит её автоматически (при необходимости переопределите путь через -Dfyi.oxide.pdf.lib.path=<path>).
Быстрый старт
Соберите PDF из Markdown, откройте его и прочитайте текст обратно. Ресурсы Pdf и PdfDocument реализуют AutoCloseable, поэтому оберните их в 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) возвращает закрываемый билдер Pdf; pdf.save() сериализует его в ByteArray. PdfDocument.open(ByteArray) открывает результат для чтения.
Открытие PDF
Откройте существующий документ из байтов и изучите его метаданные. producerOrNull() и creatorOrNull() — это nullable-представления Kotlin поверх Java-геттеров, возвращающих Optional:
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)"}")
}
Извлечение текста
Извлекайте обычный текст с любой страницы по её индексу (с нуля) или пройдите по всем страницам в цикле:
import fyi.oxide.pdf.PdfDocument
PdfDocument.open(pdfBytes).use { doc ->
// одна страница
println(doc.extractText(0))
// все страницы
for (i in 0 until doc.pageCount()) {
println("--- Page ${i + 1} ---")
println(doc.extractText(i))
}
}
Элементы страницы
doc.page(i) возвращает PdfPage со структурированной геометрией — словами, строками, символами, таблицами, изображениями и аннотациями. Каждое слово несёт свой текст и ограничивающий прямоугольник:
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}")
}
bbox() слова — это BBox со вспомогательными методами вроде width() и height().
Конвертация в Markdown и HTML
Преобразуйте весь документ в Markdown или отрендерите страницу в HTML:
import fyi.oxide.pdf.PdfDocument
PdfDocument.open(pdfBytes).use { doc ->
val markdown = doc.toMarkdown() // все страницы
println(markdown)
val html = doc.toHtml()
println(html)
}
Поиск
Ищите текст по всему документу. Каждое совпадение предоставляет свой текст через text():
import fyi.oxide.pdf.PdfDocument
PdfDocument.open(pdfBytes).use { doc ->
val matches = doc.search("configuration")
matches.forEach { m ->
println("match: ${m.text()}")
}
}
Автоматическое извлечение
AutoExtractor запускает полный конвейер извлечения одним вызовом и возвращает AutoResult с текстом и опциональными представлениями в Markdown/HTML. Расширения markdownOrNull() / htmlOrNull() превращают Java-возвраты Optional в 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) }
}
Редактирование
DocumentEditor открывает PDF для структурных изменений — например, для очистки метаданных перед отправкой — а затем сериализует результат обратно в байты:
import fyi.oxide.pdf.DocumentEditor
DocumentEditor.open(pdfBytes).use { editor ->
editor.scrubMetadata()
val cleaned: ByteArray = editor.save()
println("cleaned: ${cleaned.size} bytes")
}
Следующие шаги
- Начало работы с Java — JVM-привязка, которую оборачивает фасад Kotlin
- Начало работы с Python — использование PDF Oxide из Python
- Извлечение текста — подробные параметры извлечения и рецепты
- Создание PDF — продвинутое создание с билдерами, шифрованием и метаданными
- Редактирование — изменение существующих PDF, аннотаций и полей форм