Початок роботи з PDF Oxide (Dart / Flutter)
PDF Oxide — це найшвидший спосіб читати PDF із Dart і Flutter: середній час видобування тексту 0.8 мс, 100% успішних результатів на 3830 PDF-файлах. Пакет pdf_oxide — це ідіоматична обгортка dart:ffi над ядром на Rust: дескриптори PDF звільняються автоматично через NativeFinalizer (а також через явний close()), C-рядки та буфери копіюються у Dart за вас, а коди помилок C-ABI постають у вигляді винятку PdfOxideError.
Встановлення
Додайте pdf_oxide до свого pubspec.yaml:
dependencies:
pdf_oxide: ^0.3.69
Потім завантажте залежності:
dart pub get
Прив’язка завантажує нативну бібліотеку (libpdf_oxide.{so,dylib,dll}) під час виконання. Порядок пошуку такий: PDF_OXIDE_LIB_PATH (повний шлях) → PDF_OXIDE_LIB_DIR → ../target/release → target/release → системний завантажувач. Для Flutter постачайте бібліотеку для відповідної платформи разом зі своїм застосунком і вказуйте на неї через PDF_OXIDE_LIB_PATH.
Швидкий старт
Відкрийте PDF і витягніть текст із першої сторінки. Завжди викликайте close() для документа, коли закінчили — try/finally тримає це в порядку.
import 'package:pdf_oxide/pdf_oxide.dart';
void main() {
final doc = PdfDocument.open('research-paper.pdf');
try {
print('Pages: ${doc.pageCount}');
print('PDF version: ${doc.version}'); // e.g. 1.7
print(doc.extractText(0));
} finally {
doc.close();
}
}
Щоб відкрити PDF, який уже знаходиться в пам’яті (наприклад, завантажений по HTTP у застосунку на Flutter), скористайтеся openFromBytes:
import 'dart:typed_data';
import 'package:pdf_oxide/pdf_oxide.dart';
void render(Uint8List bytes) {
final doc = PdfDocument.openFromBytes(bytes);
try {
print(doc.extractText(0));
} finally {
doc.close();
}
}
Текст, Markdown і HTML
Кожну сторінку можна відрендерити як звичайний текст, Markdown або HTML. Методи для окремої сторінки приймають індекс сторінки з нуля; варіанти з …All() працюють по всьому документу.
import 'package:pdf_oxide/pdf_oxide.dart';
void main() {
final doc = PdfDocument.open('report.pdf');
try {
// Single page (index 0)
print(doc.extractText(0)); // raw extracted text
print(doc.toPlainText(0)); // normalized plain text
print(doc.toMarkdown(0)); // Markdown with headings, lists, tables
print(doc.toHtml(0)); // HTML
// Whole document
print(doc.toMarkdownAll());
print(doc.toHtmlAll());
print(doc.toPlainTextAll());
} finally {
doc.close();
}
}
Є також полегшене подання Page, якщо вам зручніше працювати по одній сторінці:
final doc = PdfDocument.open('report.pdf');
final page = doc.page(0);
print(page.text());
print(page.markdown());
doc.close();
Слова та рядки з координатами
extractWords повертає кожне слово з його обмежувальним прямокутником, шрифтом і насиченістю; extractTextLines повертає цілі рядки. Координати наведені в точках користувацького простору PDF.
import 'package:pdf_oxide/pdf_oxide.dart';
void main() {
final doc = PdfDocument.open('paper.pdf');
try {
for (final word in doc.extractWords(0)) {
final b = word.bbox; // Bbox(x, y, width, height)
print("'${word.text}' at (${b.x}, ${b.y}) "
'font=${word.fontName} size=${word.fontSize} bold=${word.bold}');
}
for (final line in doc.extractTextLines(0)) {
print('${line.wordCount} words: ${line.text}');
}
} finally {
doc.close();
}
}
Для деталізації на рівні гліфів extractChars повертає кожен Char із його кодовою позицією Unicode, обмежувальним прямокутником, назвою шрифту та розміром:
final doc = PdfDocument.open('paper.pdf');
for (final ch in doc.extractChars(0)) {
print('${String.fromCharCode(ch.character)} @ ${ch.bbox} ${ch.fontSize}pt');
}
doc.close();
Пошук
search шукає в межах однієї сторінки; searchAll сканує весь документ. Обидва приймають пошуковий запит і прапорець caseSensitive, а повертають записи SearchResult, які містять знайдений текст, індекс його сторінки та обмежувальний прямокутник.
import 'package:pdf_oxide/pdf_oxide.dart';
void main() {
final doc = PdfDocument.open('manual.pdf');
try {
// Single page (page 0), case-insensitive
for (final hit in doc.search(0, 'configuration', false)) {
print("page ${hit.page}: '${hit.text}' at ${hit.bbox}");
}
// Across the whole document
final hits = doc.searchAll('configuration', false);
print('${hits.length} matches');
} finally {
doc.close();
}
}
Створення PDF
Будівник Pdf перетворює Markdown, HTML або звичайний текст на PDF. Викличте toBytes(), щоб отримати байти, або save(), щоб записати файл, і close() після завершення.
import 'package:pdf_oxide/pdf_oxide.dart';
void main() {
final pdf = Pdf.fromMarkdown('# Hello World\n\nThis is a **PDF**.\n');
try {
pdf.save('output.pdf');
final bytes = pdf.toBytes();
print('Wrote ${bytes.length} bytes');
} finally {
pdf.close();
}
}
Pdf.fromHtml('<h1>Invoice</h1><p>Amount: \$42</p>') і Pdf.fromText('Plain text content.') працюють так само. Оскільки побудований Pdf — це просто байти, ви можете передати їх напряму в PdfDocument.openFromBytes(pdf.toBytes()), щоб видобути їх назад, не звертаючись до диска.
Обробка помилок
Кожен виклик, який може завершитися невдачею, кидає PdfOxideError (який implements Exception), несучи відповідний код помилки C-ABI:
import 'package:pdf_oxide/pdf_oxide.dart';
void main() {
try {
final doc = PdfDocument.open('/nonexistent/nope.pdf');
doc.close();
} on PdfOxideError catch (e) {
print('Failed to open PDF: $e');
}
}
Наступні кроки
- Початок роботи з Rust — нативне ядро, що живить цю прив’язку
- Початок роботи з Python — використання PDF Oxide із Python
- Видобування тексту — детальні опції та рецепти видобування
- Створення PDF — розширене створення з метаданими та шифруванням