Office ドキュメントの編集
EditableDocument は Document の read-modify-write 版です。変更されていない OPC パーツ(画像、グラフ、スタイル、テーマ、リレーションシップ)をすべてそのまま保持するため、編集によって周囲のコンテンツが再配置されたり、下流のコンシューマが無効になったりすることはありません。
編集は DOCX、XLSX、PPTX に対応しています。レガシー形式の DOC、XLS、PPT は読み取り専用です。編集が必要な場合は、まず save_as で変換してください。
できること
| 操作 | DOCX | XLSX | PPTX | メソッド |
|---|---|---|---|---|
| 本文・プレースホルダーのテキスト置換 | ✓ | — | ✓ | replace_text |
| セル値の設定(文字列・数値・真偽値・空値) | — | ✓ | — | set_cell |
| ディスクへの保存 | ✓ | ✓ | ✓ | save |
| バイト列への保存 | ✓ | ✓ | ✓ | save_to_bytes |
XLSX に対して replace_text を呼び出すと 0 が返ります(<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 パーツとバイナリパーツ(画像、フォント、埋め込みオブジェクト)を含んでいます。単純なエディターは保存時にすべてのパーツを再シリアライズするため、以下の問題が起きることがあります。
- リレーションシップが並べ替えられ、リンクが壊れる
- エディターが認識しない拡張パーツが失われる(カスタム XML、AlternateContent フォールバックなど)
- XML が再フォーマットされ、下流の差分や署名が壊れる
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")?;
フォーマット固有のエディターは各バインディングのリファレンスに記載されています(Rust: docx::edit、xlsx::edit、pptx::edit)。
関連項目
- テキスト置換 —
replace_textAPI の詳細 - XLSX セルの設定 — セルの型、フォーマット、エッジケース
- 変換 — レガシー DOC/XLS/PPT を編集可能な OOXML へ先に変換する