Erste Schritte mit PDF Oxide (Clojure)
PDF Oxide ist das schnellste PDF-Toolkit mit integrierter Textextraktion — 0,8 ms im Mittel, 100 % Erfolgsquote bei 3.830 PDFs. Das Clojure-Binding ist ein idiomatischer, schlanker Wrapper über dem ausgereiften Java-Binding fyi.oxide:pdf-oxide, das die einzige native JNI-Brücke besitzt. Es fügt keinerlei nativen Code hinzu: Es ruft die Java-Klassen per Interop auf und liefert Clojure-freundliche Werte zurück (java.util.List → Vektor, java.util.Optional → Wert-oder-nil).
Installation
Füge das Java-Binding zu deiner deps.edn hinzu. Der Clojure-Namespace (pdf_oxide.core) liegt in deinem Quellbaum und umschließt es:
{:deps {fyi.oxide/pdf-oxide {:mvn/version "0.3.69"}}}
Die Handle-Typen (Pdf, PdfDocument, DocumentEditor) sind AutoCloseable, verwende daher with-open für eine deterministische Freigabe.
Schnellstart
Erstelle ein PDF aus Markdown, öffne es wieder und extrahiere seinen Text. Jeder Schritt liefert reine Clojure-Werte zurück.
(require '[pdf-oxide.core :as pdf])
(with-open [p (pdf/from-markdown "# Hello\n\nbody\n")
d (pdf/open (pdf/save p))]
(println "pages: " (pdf/page-count d))
(println "producer:" (or (pdf/producer d) "(none)"))
(println (pdf/extract-text d 0)))
Ein PDF öffnen
pdf/open akzeptiert entweder ein Byte-Array oder einen Dateipfad als String, mit einem optionalen Passwort für verschlüsselte Dokumente.
(require '[pdf-oxide.core :as pdf])
;; Aus einem Pfad
(with-open [d (pdf/open "research-paper.pdf")]
(println "pages:" (pdf/page-count d)))
;; Aus Bytes (z. B. von S3 oder HTTP heruntergeladen)
(with-open [d (pdf/open pdf-bytes)]
(println (pdf/extract-text d 0)))
;; Verschlüsseltes Dokument
(with-open [d (pdf/open "confidential.pdf" "secret")]
(println (pdf/extract-text d 0)))
Du kannst dich auch nach dem Öffnen authentifizieren:
(with-open [d (pdf/open "confidential.pdf")]
(when (pdf/authenticate d "secret")
(println (pdf/extract-text d 0))))
Textextraktion
Extrahiere reinen Text aus einer beliebigen Seite über ihren nullbasierten Index.
(require '[pdf-oxide.core :as pdf])
(with-open [d (pdf/open "report.pdf")]
;; Eine einzelne Seite
(println (pdf/extract-text d 0))
;; Alle Seiten
(doseq [i (range (pdf/page-count d))]
(println "--- Page" (inc i) "---")
(println (pdf/extract-text d i))))
Seitenelemente
pdf/page liefert eine PdfPage zurück. Daraus kannst du Wörter, Zeilen, Zeichen, Tabellen, Bilder und Annotationen abrufen — jeweils als Clojure-Vektor. Wort-, Zeilen- und Zeichenobjekte stellen .text und .bbox per Interop bereit.
(require '[pdf-oxide.core :as pdf])
(with-open [d (pdf/open "paper.pdf")]
(let [pg (pdf/page d 0)]
(println "page width:" (.width pg))
;; Wörter mit ihren Begrenzungsrahmen
(doseq [w (take 8 (pdf/words pg))]
(println " " (.text w) "@" (.bbox w)))
;; Weitere Element-Vektoren
(println "lines: " (count (pdf/lines pg)))
(println "chars: " (count (pdf/chars pg)))
(println "tables: " (count (pdf/tables pg)))
(println "images: " (count (pdf/images pg)))
(println "annotations:" (count (pdf/annotations pg)))
;; Reiner Text für die ganze Seite oder einen ausgeschnittenen Bereich (BBox)
(println (pdf/page-text pg))))
Um die Extraktion auf einen Bereich zu beschränken, übergib eine fyi.oxide.pdf.geometry.BBox:
(import '[fyi.oxide.pdf.geometry BBox])
(with-open [d (pdf/open "paper.pdf")]
(let [pg (pdf/page d 0)]
(println (pdf/page-text pg (BBox. 0.0 0.0 1000.0 1000.0)))))
Markdown- & HTML-Konvertierung
Konvertiere das gesamte Dokument oder eine einzelne Seite nach Markdown oder HTML.
(require '[pdf-oxide.core :as pdf])
(with-open [d (pdf/open "paper.pdf")]
;; Gesamtes Dokument
(println (pdf/to-markdown d))
(println (pdf/to-html d))
;; Eine einzelne Seite (nullbasiert)
(println (pdf/to-markdown d 0))
(println (pdf/to-html d 0)))
Für eine reichhaltigere Struktur liefert pdf/extract-structured den strukturierten Elementbaum einer Seite:
(with-open [d (pdf/open "paper.pdf")]
(println (pdf/extract-structured d 0)))
Suche
pdf/search durchsucht das gesamte Dokument und liefert einen Vektor von Treffer-Objekten zurück. Jeder Treffer stellt .text per Interop bereit.
(require '[pdf-oxide.core :as pdf])
(with-open [d (pdf/open "manual.pdf")]
(doseq [m (pdf/search d "configuration")]
(println (.text m))))
Rendering
Rendere eine Seite in ein PNG-Byte-Array, optional mit einer gewählten DPI-Auflösung.
(require '[pdf-oxide.core :as pdf]
'[clojure.java.io :as io])
(with-open [d (pdf/open "paper.pdf")]
;; Standard-DPI
(io/copy (pdf/render d 0) (io/file "page-0.png"))
;; Explizite DPI
(io/copy (pdf/render d 0 150) (io/file "page-0@150.png")))
Erstellung
Der Typ Pdf stellt Factory-Funktionen bereit. pdf/save serialisiert ein erstelltes Pdf in ein Byte-Array.
(require '[pdf-oxide.core :as pdf]
'[clojure.java.io :as io])
;; Aus Markdown
(with-open [p (pdf/from-markdown "# Hello World\n\nThis is a PDF.")]
(io/copy (pdf/save p) (io/file "output.pdf")))
;; Aus HTML
(with-open [p (pdf/from-html "<h1>Invoice</h1><p>Amount: $42</p>")]
(io/copy (pdf/save p) (io/file "invoice.pdf")))
Bearbeitung & Schwärzung
pdf/editor öffnet einen DocumentEditor (aus einem Byte-Array oder Pfad) für strukturelle Bearbeitungen. Metadaten bereinigen, Bereiche zur Schwärzung markieren und sie destruktiv anwenden, dann mit pdf/editor-save serialisieren.
(require '[pdf-oxide.core :as pdf]
'[clojure.java.io :as io])
(import '[fyi.oxide.pdf.geometry BBox])
(with-open [ed (pdf/editor "form.pdf")]
(pdf/scrub-metadata ed)
(pdf/add-redaction ed 0 (BBox. 10.0 10.0 50.0 20.0))
(pdf/apply-redactions ed)
(io/copy (pdf/editor-save ed) (io/file "redacted.pdf")))
Metadaten & Lebenszyklus
pdf/producer und pdf/creator liefern die Dokumentmetadaten als Wert zurück, oder nil, wenn sie fehlen (java.util.Optional wird automatisch für dich ausgepackt). Bevorzuge with-open; pdf/close und pdf/open? sind Notausstiege für die manuelle Verwaltung des Lebenszyklus.
(require '[pdf-oxide.core :as pdf])
(let [d (pdf/open "paper.pdf")]
(println "open? " (pdf/open? d))
(println "producer:" (or (pdf/producer d) "(none)"))
(println "creator: " (or (pdf/creator d) "(none)"))
(pdf/close d)
(println "open? " (pdf/open? d)))
Nächste Schritte
- Erste Schritte mit Java – das Java-Binding, auf dem dieser Wrapper aufbaut
- Textextraktion – detaillierte Extraktionsoptionen und Rezepte
- PDF-Erstellung – fortgeschrittene Erstellung mit Metadaten und Styling
- Bearbeitung – vorhandene PDFs ändern, Annotationen und Schwärzung