Skip to content

Редактирование текста

PDF Oxide предоставляет DOM-подобное редактирование текста через объект PdfPage. Вы можете запрашивать текстовые элементы, изменять их содержимое и сохранять изменения обратно в PDF. Каждый текстовый элемент представлен как узел PdfText с доступом к содержимому, метаданным шрифта, ограничивающему прямоугольнику и позиционированию.

Получение страницы

Python

from pdf_oxide import PdfDocument

doc = PdfDocument("input.pdf")
page = doc.page(0)  # Get page at index 0

Rust

Используйте API Pdf:

use pdf_oxide::api::Pdf;

let mut doc = Pdf::open("input.pdf")?;
let page = doc.page(0)?;

Or use DocumentEditor directly:

use pdf_oxide::editor::DocumentEditor;

let mut editor = DocumentEditor::open("input.pdf")?;
let page = editor.get_page(0)?;

Поиск текста

find_text_containing

Поиск текстовых элементов, содержащих указанную строку.

page = doc.page(0)
texts = page.find_text_containing("Hello")
for t in texts:
    print(f"Found: '{t.value}' at {t.bbox}")
let page = doc.page(0)?;
let texts = page.find_text_containing("Hello");
for t in &texts {
    println!("Found: '{}' at {:?}", t.text(), t.bbox());
}

find_text (Rust only)

Поиск с пользовательским предикатом для более гибкого сопоставления.

// Find all bold text larger than 14pt
let headings = page.find_text(|t| t.is_bold() && t.font_size() > 14.0);
for h in &headings {
    println!("Heading: {}", h.text());
}

// Find text by font name
let courier_text = page.find_text(|t| t.font_name().contains("Courier"));

Изменение текста

set_text

Заменить содержимое текстового элемента по его ID.

page = doc.page(0)
for t in page.find_text_containing("DRAFT"):
    page.set_text(t.id, "FINAL")
doc.save_page(page)
doc.save("output.pdf")
let mut page = doc.page(0)?;
let drafts = page.find_text_containing("DRAFT");
for t in &drafts {
    page.set_text(t.id(), "FINAL")?;
}
doc.save_page(page)?;
doc.save("output.pdf")?;

modify_text (Rust only)

Применить замыкание для изменения текстового элемента на месте с доступом к полному API PdfText.

let mut page = doc.page(0)?;
let texts = page.find_text_containing("price");
for t in &texts {
    page.modify_text(t.id(), |text| {
        let old = text.text().to_string();
        let new = old.replace("$9.99", "$12.99");
        text.set_text(new);
    })?;
}
doc.save_page(page)?;

Свойства PdfText

Каждый элемент PdfText предоставляет доступ для чтения своих свойств.

Python

page = doc.page(0)
for t in page.find_text_containing(""):
    print(f"Text: {t.value}")
    print(f"Font: {t.font_name} {t.font_size}pt")
    print(f"Bold: {t.is_bold}, Italic: {t.is_italic}")
    print(f"BBox: {t.bbox}")
    print(f"Contains 'hello': {t.contains('hello')}")
    print(f"Starts with 'A': {t.starts_with('A')}")
    print(f"Ends with '.': {t.ends_with('.')}")

Rust

let page = doc.page(0)?;
for t in &page.find_text_containing("") {
    println!("Text: {}", t.text());
    println!("Font: {} {:.1}pt", t.font_name(), t.font_size());
    println!("Bold: {}, Italic: {}", t.is_bold(), t.is_italic());
    println!("BBox: {:?}", t.bbox());
    println!("Color: {:?}", t.color());

    // String operations
    println!("Contains 'hello': {}", t.contains("hello"));
    println!("Starts with 'A': {}", t.starts_with("A"));
    println!("Ends with '.': {}", t.ends_with("."));
    println!("Empty: {}", t.is_empty());
    println!("Length: {}", t.len());
}

Полный API PdfText (Rust)

Методы содержимого

Метод Возвращает Описание
text() &str Получить текстовое содержимое
value() &str Alias for text()
set_text(new_text) () Заменить текстовое содержимое
set_value(new_text) () Alias for set_text()
append(text) () Добавить текст to the end
replace(old, new) usize Заменить вхождения, returns count
clear() () Удалить всё текстовое содержимое
is_empty() bool Проверить, пуст ли текст
len() usize Получить длину текста
contains(needle) bool Проверить, содержит ли текст подстроку
starts_with(prefix) bool Проверить наличие префикса
ends_with(suffix) bool Проверить наличие суффикса

Методы шрифтов и стилей

Метод Возвращает Описание
font_name() &str Имя шрифта PostScript
font_size() f32 Размер шрифта в пунктах
is_bold() bool Проверить жирность
is_italic() bool Проверить курсивность
color() Color Цвет текста
set_style(style) () Установить стиль текста

Методы позиции и трансформации

Метод Возвращает Описание
id() ElementId Уникальный идентификатор элемента
bbox() Rect Ограничивающий прямоугольник
origin() Option<Point> Точка начала текста
set_origin(point) () Установить начало текста
rotation_degrees() Option<f32> Поворот в градусах
rotation_radians() Option<f32> Поворот в радианах
set_rotation(degrees) () Установить угол поворота
is_rotated() bool Проверить, повёрнут ли текст
matrix() Option<[f32; 6]> Матрица трансформации
set_matrix(matrix) () Установить матрицу трансформации

Продвинутые примеры

Поиск и замена по всем страницам

from pdf_oxide import PdfDocument

doc = PdfDocument("contract.pdf")

for i in range(doc.page_count()):
    page = doc.page(i)
    texts = page.find_text_containing("Acme Corp")
    for t in texts:
        page.set_text(t.id, "NewCo Inc.")
    doc.save_page(page)

doc.save("contract-updated.pdf")
use pdf_oxide::api::Pdf;

let mut doc = Pdf::open("contract.pdf")?;
let count = doc.page_count()?;

for i in 0..count {
    let mut page = doc.page(i)?;
    let texts = page.find_text_containing("Acme Corp");
    for t in &texts {
        page.set_text(t.id(), "NewCo Inc.")?;
    }
    doc.save_page(page)?;
}
doc.save("contract-updated.pdf")?;

Использование PageEditor (Rust)

PageEditor предоставляет fluent API для пакетных операций редактирования.

use pdf_oxide::editor::DocumentEditor;

let mut editor = DocumentEditor::open("input.pdf")?;

editor.edit_page(0, |page| {
    let texts = page.find_text_containing("old");
    for t in &texts {
        page.set_text(t.id(), "new")?;
    }
    Ok(())
})?;

editor.save("output.pdf")?;

Или используя PageEditor напрямую для операций на основе коллекций:

let mut editor = DocumentEditor::open("input.pdf")?;

let page = editor.page_editor(0)?
    .find_text_containing("price")?
    .for_each(|text| {
        let old = text.text().to_string();
        text.set_text(old.replace("$9.99", "$12.99"));
    })?
    .done()?;

editor.save_page_from_editor(page)?;
editor.save("output.pdf")?;

Добавление нового текста на страницу

page = doc.page(0)
text_id = page.add_text("CONFIDENTIAL", 100, 750, 24.0)
doc.save_page(page)
doc.save("stamped.pdf")
use pdf_oxide::elements::{FontSpec, TextContent, TextStyle};

let mut page = doc.page(0)?;
let content = TextContent {
    text: "CONFIDENTIAL".to_string(),
    bbox: pdf_oxide::geometry::Rect::new(100.0, 750.0, 200.0, 24.0),
    font: FontSpec {
        name: "Helvetica-Bold".to_string(),
        size: 24.0,
    },
    style: TextStyle::default(),
    reading_order: None,
    origin: None,
    rotation_degrees: None,
    matrix: None,
};
let id = page.add_text(content);
doc.save_page(page)?;

Удаление текстовых элементов

page = doc.page(0)
for t in page.find_text_containing("DELETE ME"):
    page.remove_element(t.id)
doc.save_page(page)
doc.save("cleaned.pdf")
let mut page = doc.page(0)?;
let to_remove = page.find_text_containing("DELETE ME");
for t in &to_remove {
    page.remove_element(t.id());
}
doc.save_page(page)?;
doc.save("cleaned.pdf")?;

Сохранение изменённых страниц

После изменения текста на странице необходимо вызвать save_page() для сохранения изменений. Без этого вызова изменения будут отброшены.

page = doc.page(0)
page.set_text(text_id, "updated")
doc.save_page(page)   # Persist page changes
doc.save("output.pdf")  # Write to disk
let mut page = doc.page(0)?;
page.set_text(text_id, "updated")?;
doc.save_page(page)?;   // Persist page changes
doc.save("output.pdf")?;  // Write to disk

Связанные страницы