将旧版 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) | 仅值 | 缓存的计算结果保留;公式表达式本身不保留 |
| WordArt、SmartArt、图表 | — | 如有需要,请在目标格式中重新创建 |
| 加密 | — | 请先解密旧版文件(例如通过 LibreOffice) |
对于绝大多数 LLM、索引和归档场景,内容级别的还原度才是关键——Office Oxide 能在毫秒内输出完全可编辑的 DOCX/XLSX/PPTX。
性能
单文件转换与文本提取处于同一数量级。典型的 Word 97 .doc 文件端到端预计耗时个位数毫秒。
相关链接
- 性能基准测试 — DOC/XLS/PPT 提取的具体数据
- 从 IR 构建 —
save_as底层的工作原理 - 从 python-docx 迁移 — 从单格式 Python 库切换过来