Skip to content

将旧版 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 文件端到端预计耗时个位数毫秒

相关链接