Початок роботи з PDF Oxide (Elixir)
PDF Oxide — це найшвидший спосіб читати й створювати PDF з Elixir: 0.8 мс середнє витягання тексту, 100% успішних на 3830 PDF. Це NIF поверх того самого ядра на Rust, який виконує роботу, навантажену на CPU, на dirty CPU schedulers (ERL_NIF_DIRTY_JOB_CPU_BOUND), тож він ніколи не блокує планувальник BEAM.
Дескриптори Document і Pdf — це ресурси NIF, які звільняє збирач сміття. Функції, що можуть завершитися помилкою, повертають {:ok, value} або {:error, code}, а індекси сторінок починаються з 0.
Встановлення
Додайте pdf_oxide до залежностей у mix.exs:
def deps do
[
{:pdf_oxide, "~> 0.3"}
]
end
Потім завантажте й скомпілюйте — NIF збирається через elixir_make на основі нативної cdylib:
mix deps.get
mix compile
Швидкий старт
Створіть PDF з Markdown, серіалізуйте його в байти, потім відкрийте й витягніть текст назад.
{:ok, pdf} = PdfOxide.from_markdown("# Hello pdf_oxide\n\nThis is an **Elixir** binding.\n")
{:ok, bytes} = PdfOxide.to_bytes(pdf)
{:ok, doc} = PdfOxide.open_from_bytes(bytes)
{:ok, pages} = PdfOxide.page_count(doc)
IO.puts("pages: #{pages}")
%{major: maj, minor: min} = PdfOxide.version(doc)
IO.puts("version: #{maj}.#{min}")
{:ok, text} = PdfOxide.extract_text(doc, 0)
IO.puts(text)
Відкриття PDF
Відкривайте за шляхом до файлу або безпосередньо з байтів у пам’яті (зручно, коли дані надходять потоком з S3, HTTP або бази даних):
# Зі шляху
{:ok, doc} = PdfOxide.open("report.pdf")
# З байтів, що вже в пам'яті
{:ok, doc} = PdfOxide.open_from_bytes(pdf_bytes)
# Зашифровані документи
{:ok, doc} = PdfOxide.open_with_password("confidential.pdf", "secret")
# Перевірка
{:ok, count} = PdfOxide.page_count(doc)
encrypted? = PdfOxide.encrypted?(doc)
Закривайте документ явно, коли закінчите (close/1 ідемпотентна), або дайте збирачу сміття звільнити його:
:ok = PdfOxide.close(doc)
Витягання тексту
Витягуйте звичайний текст з окремої сторінки за її індексом, що починається з нуля, або одразу з усього документа:
{:ok, doc} = PdfOxide.open("book.pdf")
# Окрема сторінка
{:ok, text} = PdfOxide.extract_text(doc, 0)
# Звичайний текст, одна сторінка
{:ok, pt} = PdfOxide.to_plain_text(doc, 0)
# Кожна сторінка, об'єднана
{:ok, all} = PdfOxide.to_plain_text_all(doc)
IO.puts(all)
Конвертація в Markdown і HTML
Конвертуйте сторінку — або весь документ — у Markdown чи HTML:
{:ok, doc} = PdfOxide.open("paper.pdf")
{:ok, md} = PdfOxide.to_markdown(doc, 0)
{:ok, mdall} = PdfOxide.to_markdown_all(doc)
{:ok, html} = PdfOxide.to_html(doc, 0)
{:ok, htmlall} = PdfOxide.to_html_all(doc)
Слова та рядки
extract_words/2 повертає структуровані структури PdfOxide.Word з обмежувальним прямокутником і прапорцем bold; extract_text_lines/2 групує їх у рядки.
{:ok, doc} = PdfOxide.open("paper.pdf")
{:ok, words} = PdfOxide.extract_words(doc, 0)
for w <- Enum.take(words, 10) do
%PdfOxide.Bbox{x: x, y: y, width: width} = w.bbox
IO.puts("#{w.text} at (#{x}, #{y}) w=#{width} bold=#{w.bold}")
end
{:ok, lines} = PdfOxide.extract_text_lines(doc, 0)
for line <- lines do
IO.puts("#{line.word_count} words: #{line.text}")
end
Пошук
Шукайте на окремій сторінці або по всьому документу. Четвертий аргумент — case_sensitive. Кожен результат містить text, page та PdfOxide.Bbox.
{:ok, doc} = PdfOxide.open("manual.pdf")
# Одна сторінка (індекс сторінки 0), без урахування регістру
{:ok, results} = PdfOxide.search(doc, 0, "configuration", false)
for r <- results do
%PdfOxide.Bbox{x: x, y: y} = r.bbox
IO.puts("page #{r.page}: '#{r.text}' at (#{x}, #{y})")
end
# Усі сторінки
{:ok, all} = PdfOxide.search_all(doc, "configuration", false)
IO.puts("#{length(all)} matches")
Створення PDF
Фабричні функції конструктора повертають дескриптор Pdf, який ви серіалізуєте за допомогою to_bytes/1 або записуєте просто на диск за допомогою save/2:
{:ok, pdf} = PdfOxide.from_markdown("# Hello World\n\nThis is a PDF.")
:ok = PdfOxide.save(pdf, "output.pdf")
{:ok, pdf} = PdfOxide.from_html("<h1>Invoice</h1><p>Amount: $42</p>")
{:ok, bytes} = PdfOxide.to_bytes(pdf)
{:ok, pdf} = PdfOxide.from_text("Plain text content.")
:ok = PdfOxide.save(pdf, "notes.pdf")
Рендеринг сторінок у зображення
Із увімкненою функцією рендерингу растеризуйте сторінку в PdfOxide.RenderedImage і збережіть її як PNG:
{:ok, doc} = PdfOxide.open("paper.pdf")
{:ok, img} = PdfOxide.render_page(doc, 0)
IO.puts("#{img.width}x#{img.height}, #{byte_size(img.data)} bytes")
:ok = PdfOxide.save(img, "page0.png")
# Коефіцієнт масштабування або мініатюра фіксованого розміру
{:ok, zoomed} = PdfOxide.render_page_zoom(doc, 0, 2.0)
{:ok, thumb} = PdfOxide.render_page_thumbnail(doc, 0, 128)
Обробка помилок
Функції, що можуть завершитися помилкою, повертають кортеж з тегом — використовуйте зіставлення зі зразком для чистого керування потоком:
case PdfOxide.open("/nonexistent/nope.pdf") do
{:ok, doc} ->
{:ok, text} = PdfOxide.extract_text(doc, 0)
IO.puts(text)
{:error, code} ->
IO.puts("could not open PDF: #{inspect(code)}")
end
Наступні кроки
- Початок роботи з Rust — використання PDF Oxide з Rust
- Початок роботи з Python — використання PDF Oxide з Python
- Витягання тексту — докладні параметри витягання та рецепти
- Створення PDF — розширене створення з метаданими та шифруванням
- Редагування — зміна наявних PDF, анотацій та полів форм