Редактирование Office-документов
EditableDocument — read-modify-write аналог Document. Он сохраняет каждую нетронутую OPC-часть — изображения, диаграммы, стили, темы, связи — дословно, поэтому ваши правки не переформатируют окружающее содержимое и не ломают потребителей дальше по цепочке.
Редактирование поддерживается для DOCX, XLSX и PPTX. Устаревшие форматы DOC, XLS и PPT — только для чтения; если нужно редактировать — сначала конвертируйте через save_as.
Что вы можете делать
| Операция | DOCX | XLSX | PPTX | Метод |
|---|---|---|---|---|
| Замена текста в теле / плейсхолдерах | ✓ | — | ✓ | replace_text |
| Запись значения ячейки (string / number / bool / empty) | — | ✓ | — | set_cell |
| Сохранение на диск | ✓ | ✓ | ✓ | save |
| Сохранение в байты | ✓ | ✓ | ✓ | save_to_bytes |
replace_text возвращает 0 при вызове на XLSX (там нет элементов <w:t> или <a:t>); для таблиц используйте set_cell.
Открыть, отредактировать, сохранить
Rust
use office_oxide::edit::EditableDocument;
let mut ed = EditableDocument::open("template.docx")?;
ed.replace_text("{{name}}", "Alice");
ed.replace_text("{{date}}", "2026-04-19");
ed.save("filled.docx")?;
Python
from office_oxide import EditableDocument
with EditableDocument.open("template.docx") as ed:
ed.replace_text("{{name}}", "Alice")
ed.replace_text("{{date}}", "2026-04-19")
ed.save("filled.docx")
JavaScript
import { EditableDocument } from 'office-oxide';
using ed = EditableDocument.open('template.docx');
ed.replaceText('{{name}}', 'Alice');
ed.replaceText('{{date}}', '2026-04-19');
ed.save('filled.docx');
Go
ed, err := officeoxide.OpenEditable("template.docx")
defer ed.Close()
ed.ReplaceText("{{name}}", "Alice")
ed.ReplaceText("{{date}}", "2026-04-19")
ed.Save("filled.docx")
C#
using var ed = EditableDocument.Open("template.docx");
ed.ReplaceText("{{name}}", "Alice");
ed.ReplaceText("{{date}}", "2026-04-19");
ed.Save("filled.docx");
C
int err = 0;
OfficeEditableHandle *ed = office_editable_open("template.docx", &err);
office_editable_replace_text(ed, "{{name}}", "Alice", &err);
office_editable_replace_text(ed, "{{date}}", "2026-04-19", &err);
office_editable_save(ed, "filled.docx", &err);
office_editable_free(ed);
Сохранение в байты (для загрузки / стриминга)
Rust
let mut ed = EditableDocument::open("template.docx")?;
ed.replace_text("{{name}}", "Alice");
let mut buf = std::io::Cursor::new(Vec::new());
ed.write_to(&mut buf)?;
let bytes: Vec<u8> = buf.into_inner();
Python
with EditableDocument.open("template.docx") as ed:
ed.replace_text("{{name}}", "Alice")
bytes_out = ed.save_to_bytes()
# upload bytes_out to S3 / send over HTTP / etc.
JavaScript
using ed = EditableDocument.open('template.docx');
ed.replaceText('{{name}}', 'Alice');
const bytes = ed.saveToBytes(); // Uint8Array
C
int err = 0;
OfficeEditableHandle *ed = office_editable_open("template.docx", &err);
office_editable_replace_text(ed, "{{name}}", "Alice", &err);
size_t out_len = 0;
uint8_t *buf = office_editable_save_to_bytes(ed, &out_len, &err);
/* stream buf[0..out_len], then: */
office_oxide_free_bytes(buf, out_len);
office_editable_free(ed);
Что на самом деле означает «сохранить OPC-части»
OOXML-файлы — это ZIP-архивы, содержащие десятки XML-частей плюс бинарные части (изображения, шрифты, внедрённые объекты). Примитивные редакторы при сохранении пересериализуют каждую часть, что может:
- Переупорядочить связи и сломать ссылки
- Удалить расширенные части, которые редактор не понимает (custom XML, fallback’и AlternateContent)
- Переформатировать XML так, что сломаются downstream-диффы и подписи
EditableDocument перезаписывает только те части, которые вы изменили. Всё остальное копируется байт за байтом. В результате получается минимально возможный дифф между входными и выходными данными — удобно для систем контроля версий, проверки подписей и передачи файлов между инструментами.
Когда стоит использовать формат-специфичный API
EditableDocument закрывает 80% случаев (шаблонизация, пакетное заполнение, запись ячеек). Для более сложных правок — добавление абзацев, вставка таблиц, изменение стилей, построение слайдов с нуля — переходите к формат-специфичным API:
use office_oxide::docx::edit::DocxEditor;
let mut docx = DocxEditor::open("report.docx")?;
docx.append_paragraph("New section", Some("Heading2"));
docx.save("report.docx")?;
Формат-специфичные редакторы задокументированы в reference-разделе каждого биндинга (Rust: docx::edit, xlsx::edit, pptx::edit).
Смотрите также
- Замена текста — API
replace_textподробно - Запись ячеек XLSX — типы ячеек, форматы и граничные случаи
- Конвертация — сначала преобразуйте устаревшие DOC/XLS/PPT в редактируемый OOXML