PDF Oxide 快速上手(Java)
PDF Oxide 是文本提取最快的 Java PDF 库——平均 0.8 ms,在 3830 个真实场景 PDF 上保持 100% 通过率。同一套 Rust 内核还交付给 Python、Go、JS 和 C#;Java 绑定是一层轻量 JNI 封装,以 JDK 11 LTS 为最低版本,并可从同一个 JAR 免费实现 Kotlin 互操作。
安装
JAR 内嵌了面向 Linux(x86_64/aarch64)、macOS(x86_64/aarch64)和 Windows(x86_64)的原生库。无需编译器或额外配置——首次调用时会自动解压出对应平台的库。
Maven
<dependency>
<groupId>fyi.oxide</groupId>
<artifactId>pdf-oxide</artifactId>
<version>0.3.69</version>
</dependency>
Gradle
// Kotlin DSL
implementation("fyi.oxide:pdf-oxide:0.3.69")
// Groovy
implementation 'fyi.oxide:pdf-oxide:0.3.69'
快速上手
打开一个 PDF 并提取文本。PdfDocument 实现了 AutoCloseable,因此请用 try-with-resources 来确定性地释放原生句柄。
import fyi.oxide.pdf.PdfDocument;
import java.nio.file.Path;
try (PdfDocument doc = PdfDocument.open(Path.of("report.pdf"))) {
System.out.println("Pages: " + doc.pageCount());
System.out.println(doc.extractText(0)); // zero-based page index
}
你可以从路径字符串、Path、原始 byte[] 或 InputStream 打开:
import fyi.oxide.pdf.PdfDocument;
byte[] pdfBytes = downloadFromS3();
try (PdfDocument doc = PdfDocument.open(pdfBytes)) {
String text = doc.extractText(0);
}
文本提取
按从 0 开始的页码索引遍历每一页:
import fyi.oxide.pdf.PdfDocument;
import java.nio.file.Path;
try (PdfDocument doc = PdfDocument.open(Path.of("book.pdf"))) {
for (int i = 0; i < doc.pageCount(); i++) {
System.out.println("--- Page " + (i + 1) + " ---");
System.out.println(doc.extractText(i));
}
}
单词级提取
PdfPage 暴露了结构化的几何信息。words() 返回一个 TextWord 列表,每个元素都包含文本、边界框和 OCR 置信度。
import fyi.oxide.pdf.PdfDocument;
import fyi.oxide.pdf.PdfPage;
import fyi.oxide.pdf.text.TextWord;
import fyi.oxide.pdf.geometry.BBox;
import java.nio.file.Path;
try (PdfDocument doc = PdfDocument.open(Path.of("paper.pdf"))) {
PdfPage page = doc.page(0);
for (TextWord word : page.words()) {
BBox b = word.bbox();
System.out.printf("'%s' at (%.1f, %.1f) conf=%.2f%n",
word.text(), b.x0(), b.y0(), word.confidence());
}
}
PdfPage 还提供了 lines()、chars()、tables()、images()、annotations(),以及 width()、height() 和用于从子区域提取的 text(BBox region)。
Markdown 转换
通过 MarkdownConverter 辅助类(或便捷方法 doc.toMarkdown(...)),可将单页或整个文档转换为 Markdown。
import fyi.oxide.pdf.PdfDocument;
import fyi.oxide.pdf.MarkdownConverter;
import java.nio.file.Files;
import java.nio.file.Path;
try (PdfDocument doc = PdfDocument.open(Path.of("report.pdf"))) {
String md = MarkdownConverter.toMarkdown(doc); // whole document
Files.writeString(Path.of("report.md"), md);
String pageMd = doc.toMarkdown(0); // single page
String pageHtml = doc.toHtml(0); // or HTML
}
搜索
search() 会扫描整个文档,返回一个 SearchMatch 列表,每个元素都带有页码索引、边界框和匹配到的文本。
import fyi.oxide.pdf.PdfDocument;
import fyi.oxide.pdf.search.SearchMatch;
import fyi.oxide.pdf.geometry.BBox;
import java.nio.file.Path;
try (PdfDocument doc = PdfDocument.open(Path.of("manual.pdf"))) {
for (SearchMatch m : doc.search("configuration")) {
BBox b = m.bbox();
System.out.printf("Page %d: '%s' at (%.0f, %.0f)%n",
m.pageIndex(), m.text(), b.x0(), b.y0());
}
}
创建 PDF
Pdf 类型可从 Markdown、HTML 或图像构建 PDF。它实现了 AutoCloseable,但没有 Cleaner 兜底机制,因此请务必显式关闭它,或放在 try-with-resources 中使用。
import fyi.oxide.pdf.Pdf;
import java.nio.file.Path;
try (Pdf pdf = Pdf.fromMarkdown("# Hello\n\nThis is a PDF.")) {
pdf.saveTo(Path.of("out.pdf"));
}
try (Pdf pdf = Pdf.fromHtml("<h1>Invoice</h1><p>Amount: $42</p>")) {
byte[] bytes = pdf.save(); // serialize to memory instead of disk
}
密码保护的 PDF
在调用 open() 时传入密码,或在捕获 PdfEncryptedException 后调用 authenticate()。
import fyi.oxide.pdf.PdfDocument;
import java.nio.file.Path;
try (PdfDocument doc = PdfDocument.open(Path.of("confidential.pdf"), "secret")) {
System.out.println(doc.extractText(0));
}
错误处理
PdfException extends RuntimeException(非受检异常),它带有类型化的子类,以及一个用于 switch 分发的 kind() 枚举。
import fyi.oxide.pdf.PdfDocument;
import fyi.oxide.pdf.exception.PdfEncryptedException;
import fyi.oxide.pdf.exception.PdfException;
import java.nio.file.Path;
try (PdfDocument doc = PdfDocument.open(Path.of("document.pdf"))) {
String text = doc.extractText(0);
} catch (PdfEncryptedException e) {
System.err.println("Password required");
} catch (PdfException e) {
switch (e.kind()) {
case PARSE -> System.err.println("Malformed PDF");
case IO -> System.err.println("I/O error");
default -> System.err.println("PDF error: " + e.getMessage());
}
}
Kotlin
同一个 JAR 可直接从 Kotlin 中使用——record 访问器会变成属性。
import fyi.oxide.pdf.PdfDocument
import java.nio.file.Path
PdfDocument.open(Path.of("report.pdf")).use { doc ->
println("Pages: ${doc.pageCount()}")
println(doc.extractText(0))
}
后续步骤
- Python 上手指南 —— 在 Python 中使用 PDF Oxide
- Rust 上手指南 —— 在 Rust 中使用 PDF Oxide
- 文本提取 —— 详细的提取选项与实用范例
- PDF 创建 —— 进阶创建、加密与元数据