Skip to content

Редактирование 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).

Смотрите также