Erste Schritte mit PDF Oxide (Scala)
PDF Oxide ist die schnellste PDF-Bibliothek für die JVM mit integrierter Textextraktion — 0,8 ms Durchschnitt, 100 % Bestehensquote bei 3.830 PDFs. Das Scala-3-Binding ist eine schlanke, idiomatische Fassade über dem ausgereiften Java-Binding: Es kommt ohne nativen Code aus und ergänzt Scala-Extension-Methoden, die aus java.util.Optional[T] ein Option[T] und aus java.util.List[T] ein Seq[T] machen. Die AutoCloseable-Handles arbeiten direkt mit scala.util.Using zusammen.
Installation
Fügen Sie die Abhängigkeit zu Ihrer build.sbt hinzu:
libraryDependencies += "fyi.oxide" % "pdf-oxide" % "0.3.69"
Die Scala-Fassade hängt vom Java-Binding fyi.oxide:pdf-oxide ab, das die einzige native JNI-Brücke verwaltet. Scala 3.3+ ist erforderlich.
Schnellstart
Erstellen Sie ein PDF aus Markdown, öffnen Sie es anschließend und extrahieren Sie den Text wieder. Using.resource schließt jedes Handle für Sie.
import fyi.oxide.pdf.{Pdf, PdfDocument, producerOption}
import scala.util.Using
Using.resource(Pdf.fromMarkdown("# Hello pdf_oxide\n\nThis is a **Scala** binding.\n")): pdf =>
Using.resource(PdfDocument.open(pdf.save())): doc =>
println(s"pages: ${doc.pageCount()}")
println(s"producer: ${doc.producerOption.getOrElse("(none)")}")
println(doc.extractText(0))
Pdf.fromMarkdown liefert ein Pdf-Handle zurück; pdf.save() serialisiert es zu einem Array[Byte]. PdfDocument.open nimmt diese Bytes entgegen und stellt die Dokument-API bereit.
Textextraktion
Reiner Text
Extrahieren Sie reinen Text aus jeder Seite über ihren nullbasierten Index.
import fyi.oxide.pdf.PdfDocument
import scala.util.Using
Using.resource(PdfDocument.open(pdfBytes)): doc =>
assert(doc.isOpen)
val text = doc.extractText(0)
println(text)
Markdown und HTML
Konvertieren Sie das gesamte Dokument mit einem einzigen Aufruf nach Markdown oder HTML.
import fyi.oxide.pdf.PdfDocument
import scala.util.Using
Using.resource(PdfDocument.open(pdfBytes)): doc =>
println(doc.toMarkdown())
println(doc.toHtml())
Seitenelemente
doc.page(i) liefert ein PdfPage zurück. Die Fassade stellt jeden Element-Extraktor über die *Seq-Extension-Methoden als Scala-Seq bereit: wordsSeq, linesSeq, charsSeq, tablesSeq, imagesSeq und annotationsSeq. Jedes TextWord enthält seinen text und eine bbox.
import fyi.oxide.pdf.{PdfDocument, wordsSeq, linesSeq, charsSeq, tablesSeq, imagesSeq, annotationsSeq}
import scala.util.Using
Using.resource(PdfDocument.open(pdfBytes)): doc =>
val page = doc.page(0)
println(s"size: ${page.width()} x ${page.height()}")
page.wordsSeq.take(8).foreach { w =>
println(s" ${w.text} @ ${w.bbox} (w=${w.bbox.width})")
}
println(s"lines: ${page.linesSeq.size}")
println(s"chars: ${page.charsSeq.size}")
println(s"tables: ${page.tablesSeq.size}")
println(s"images: ${page.imagesSeq.size}")
println(s"annotations: ${page.annotationsSeq.size}")
Sie können auch jede Seite als Seq über doc.pagesSeq durchlaufen (deren Größe entspricht doc.pageCount()).
import fyi.oxide.pdf.{PdfDocument, pagesSeq, wordsSeq}
import scala.util.Using
Using.resource(PdfDocument.open(pdfBytes)): doc =>
doc.pagesSeq.zipWithIndex.foreach { (page, i) =>
println(s"page $i: ${page.wordsSeq.size} words")
}
Suche
doc.searchSeq(query) liefert ein Seq[SearchMatch] zurück. Jeder Treffer stellt seinen text bereit.
import fyi.oxide.pdf.{PdfDocument, searchSeq}
import scala.util.Using
Using.resource(PdfDocument.open(pdfBytes)): doc =>
val matches = doc.searchSeq("Hello")
println(s"${matches.size} match(es)")
matches.foreach(m => println(s" ${m.text}"))
Metadaten als Option
Nullbare Dokument-Metadaten erscheinen über producerOption und creatorOption als Option[String], sodass Sie fehlende Werte auf die Scala-typische Art behandeln.
import fyi.oxide.pdf.{PdfDocument, producerOption, creatorOption}
import scala.util.Using
Using.resource(PdfDocument.open(pdfBytes)): doc =>
println(doc.producerOption.getOrElse("(unknown producer)"))
println(doc.creatorOption.getOrElse("(unknown creator)"))
// Formularfelder kommen ebenfalls als Seq zurück:
println(s"form fields: ${doc.formFieldsSeq.size}")
Rendering
doc.render(i) rastert eine Seite und liefert die codierten Bild-Bytes zurück.
import fyi.oxide.pdf.PdfDocument
import scala.util.Using
Using.resource(PdfDocument.open(pdfBytes)): doc =>
val png = doc.render(0)
java.nio.file.Files.write(java.nio.file.Path.of("page-0.png"), png)
Automatische Extraktion
AutoExtractor.of(doc).extractDocument() liefert ein AutoResult mit dem extrahierten text, optionalen markdown/html-Darstellungen und der Liste der Seiten, die noch OCR benötigen — alles idiomatisch über die Fassade bereitgestellt (markdownOption, htmlOption, pagesNeedingOcrSeq).
import fyi.oxide.pdf.{PdfDocument, AutoExtractor, markdownOption, htmlOption, pagesNeedingOcrSeq}
import scala.util.Using
Using.resource(PdfDocument.open(pdfBytes)): doc =>
val result = AutoExtractor.of(doc).extractDocument()
println(result.text)
result.markdownOption.foreach(println)
result.htmlOption.foreach(println)
println(s"pages needing OCR: ${result.pagesNeedingOcrSeq}")
Bearbeitung
DocumentEditor.open öffnet ein vorhandenes PDF für strukturelle Bearbeitungen. Hier entfernen wir die Metadaten und serialisieren das Ergebnis wieder zu Bytes.
import fyi.oxide.pdf.DocumentEditor
import scala.util.Using
Using.resource(DocumentEditor.open(pdfBytes)): editor =>
assert(editor.isOpen)
editor.scrubMetadata()
val cleaned: Array[Byte] = editor.save()
java.nio.file.Files.write(java.nio.file.Path.of("scrubbed.pdf"), cleaned)
Nächste Schritte
- Erste Schritte mit Rust – PDF Oxide aus Rust verwenden
- Erste Schritte mit Python – PDF Oxide aus Python verwenden
- Textextraktion – detaillierte Extraktionsoptionen und Rezepte
- PDF-Erstellung – fortgeschrittene Erstellung, Verschlüsselung und Metadaten
- Bearbeitung – vorhandene PDFs, Annotationen und Formularfelder bearbeiten