レガシー DOC・XLS・PPT を OOXML に変換する
Office Oxide は、Word 97–2003(.doc)、Excel 97–2003(.xls)、PowerPoint 97–2003(.ppt)を読み込み、それぞれのモダンな OOXML 形式に書き出せる唯一の Rust / Python ライブラリです。JVM(Apache Tika)も外部コンバーター(LibreOffice headless)も商用ライセンス(Aspose)も必要ありません。
save_as を呼び出すだけで変換が完了します。レガシーファイルを開き、モダンな拡張子で保存するだけで、Office Oxide が IR を経由してクリーンな OOXML コンテナを生成します。
ワンライナー
Rust
use office_oxide::Document;
Document::open("old.doc")?.save_as("modern.docx")?;
Document::open("old.xls")?.save_as("modern.xlsx")?;
Document::open("old.ppt")?.save_as("modern.pptx")?;
Python
from office_oxide import Document
with Document.open("old.doc") as doc:
doc.save_as("modern.docx")
with Document.open("old.xls") as doc:
doc.save_as("modern.xlsx")
with Document.open("old.ppt") as doc:
doc.save_as("modern.pptx")
JavaScript
import { Document } from 'office-oxide';
using doc = Document.open('old.xls');
doc.saveAs('modern.xlsx');
Go
doc, _ := officeoxide.Open("old.xls")
defer doc.Close()
doc.SaveAs("modern.xlsx")
C#
using var doc = Document.Open("old.xls");
doc.SaveAs("modern.xlsx");
C
int err = 0;
OfficeDocumentHandle *doc = office_document_open("old.xls", &err);
if (!doc) { fprintf(stderr, "open failed: code=%d\n", err); return 1; }
/* target format inferred from the extension; legacy -> OOXML converts transparently */
if (office_document_save_as(doc, "modern.xlsx", &err) != 0) {
fprintf(stderr, "save_as failed: code=%d\n", err);
}
office_document_free(doc);
一括移行
大量のファイルをワンライナーで移行できます。
Rust
use office_oxide::Document;
use std::path::Path;
fn migrate(src: &Path, dst: &Path) -> office_oxide::Result<()> {
Document::open(src)?.save_as(dst)?;
Ok(())
}
Python
from pathlib import Path
from office_oxide import Document
for src in Path("legacy").rglob("*"):
if src.suffix.lower() in {".doc", ".xls", ".ppt"}:
new_ext = {".doc": ".docx", ".xls": ".xlsx", ".ppt": ".pptx"}[src.suffix.lower()]
dst = Path("modern") / src.relative_to("legacy").with_suffix(new_ext)
dst.parent.mkdir(parents=True, exist_ok=True)
with Document.open(src) as doc:
doc.save_as(dst)
print(f"{src} → {dst}")
C
/* migrate one file: open from path, save_as routes by the dst extension */
int migrate(const char *src, const char *dst) {
int err = 0;
OfficeDocumentHandle *doc = office_document_open(src, &err);
if (!doc) return err;
int rc = office_document_save_as(doc, dst, &err);
office_document_free(doc);
return rc == 0 ? 0 : err;
}
大規模なコーパスを並列処理する場合は、ループを rayon でラップしてください。
Shell — CLI を使う
find legacy/ -iname '*.doc' | parallel \
'office-oxide convert {} modern/{/.}.docx'
find legacy/ -iname '*.xls' | parallel \
'office-oxide convert {} modern/{/.}.xlsx'
find legacy/ -iname '*.ppt' | parallel \
'office-oxide convert {} modern/{/.}.pptx'
ラウンドトリップで保持される内容
Office Oxide はコンテンツの構造(段落、表、セル、スライド、リスト、見出し)とその内容を保持します。レガシー形式が IR でモデル化されていない独自構造にエンコードしているため、一部のカテゴリは引き継がれません。
| カテゴリ | 保持 | 備考 |
|---|---|---|
| 段落テキスト | ✓ | 太字・斜体・下線の文字装飾を含む |
| リスト | ✓ | 番号付き・番号なし両対応 |
| 表 | ✓ | セル、行の順序、ヘッダー行 |
| XLSX セル値(文字列・数値・真偽値) | ✓ | — |
| シート名 | ✓ | — |
| スライドのタイトルと本文 | ✓ | — |
| ハイパーリンク | ✓ | — |
| 画像 | 一部 | DOC/PPT はインライン画像を保持、XLS の画像アンカーは破棄 |
| コメント・リビジョン | — | 変更の追跡はフラット化される |
| 数式(XLS) | 値のみ | 数式の計算結果は保持されるが、数式の式はラウンドトリップされない |
| ワードアート・スマートアート・グラフ | — | 必要な場合は変換先の形式で再作成してください |
| 暗号化 | — | 先にレガシーファイルを復号してください(LibreOffice などで) |
LLM、インデックス作成、アーカイブ用途では、コンテンツレベルの再現性が重要です。Office Oxide は数ミリ秒で完全に編集可能な DOCX/XLSX/PPTX を生成します。
パフォーマンス
ファイル単位の変換はテキスト抽出とほぼ同じ処理時間で完了します。一般的な Word 97 の .doc ファイルであれば、エンドツーエンドで一桁ミリ秒程度を見込んでください。
関連項目
- パフォーマンスベンチマーク — DOC/XLS/PPT の抽出処理の数値
- IR からの生成 —
save_asの内部動作 - python-docx からの移行 — 形式ごとの Python ライブラリからの切り替え