与格式无关的 IR
DocumentIR 是 Office Oxide 在不同格式之间的结构桥梁。无论你打开 .docx、.xlsx 还是旧版的 .ppt,都会得到同样的形态:一组 section,每个 section 内包含一系列带类型的元素(标题、段落、表格、列表、图片)。
IR 支撑了 to_html、save_as 和旧版 → OOXML 转换。它也是下游管道(搜索索引、RAG 切块器、自定义渲染器)最合适的接口 — 因为你只需处理 一个 schema,而不是 6 个按格式各异的 schema。
读取 IR
Rust
use office_oxide::Document;
let doc = Document::open("report.docx")?;
let ir = doc.to_ir();
for section in &ir.sections {
println!("{:?}", section.title);
for el in §ion.elements {
// el 是 Element 枚举 — Heading、Paragraph、Table、List、Image 等
}
}
Python
from office_oxide import Document
with Document.open("report.docx") as doc:
ir = doc.to_ir()
for section in ir["sections"]:
print(section.get("title"))
for el in section["elements"]:
kind = el["kind"] # "Heading" | "Paragraph" | "Table" | "List" | "Image"
JavaScript
using doc = Document.open('report.docx');
const ir = doc.toIr();
for (const section of ir.sections) {
for (const el of section.elements) {
// el.kind: "Heading" | "Paragraph" | "Table" | "List" | "Image"
}
}
Go
import "encoding/json"
irJSON, _ := doc.ToIRJSON()
var ir struct {
Sections []struct {
Title *string `json:"title"`
Elements []json.RawMessage `json:"elements"`
} `json:"sections"`
}
_ = json.Unmarshal([]byte(irJSON), &ir)
C#
using System.Text.Json;
using var doc = Document.Open("report.docx");
using var ir = JsonDocument.Parse(doc.ToIrJson());
foreach (var section in ir.RootElement.GetProperty("sections").EnumerateArray())
{
// ...
}
Schema
形态有意保持紧凑、稳定。
{
"sections": [
{
"title": "可选的 section 标题", // string | null
"elements": [
{ "kind": "Heading", "level": 1, "text": "..." },
{ "kind": "Paragraph", "runs": [
{ "text": "Hello ", "bold": false, "italic": false },
{ "text": "world", "bold": true, "italic": false }
] },
{ "kind": "List", "ordered": true, "items": ["one", "two"] },
{ "kind": "Table", "rows": [
["A1", "B1"],
["A2", "B2"]
] },
{ "kind": "Image", "filename": "image1.png", "data": "<base64>" }
]
}
]
}
各格式的映射:
| 格式 | section 边界 | 备注 |
|---|---|---|
| DOCX | 每个 <w:sectPr> 一个 section(没有的话整篇 body 一个) |
标题按 w:pStyle 分类 |
| XLSX | 每个工作表一个 section | title = 工作表名;每个使用范围一个 Table 元素 |
| PPTX | 每张幻灯片一个 section | title = 标题占位符;备注作为最后一个段落附上 |
| DOC / XLS / PPT | 与对应 OOXML 形态相同 | 走旧版 CFB 解析管线 |
为什么用 IR
- 构建一次,多种渲染。把 DOCX、XLSX、PPTX 转成同一形态,跑同一个搜索/分块管线。
- 跨格式变化的 LLM 上下文。源文件从
.doc改成.docx时 schema 不会漂移。 save_as实现往返。改 IR,然后写出任何受支持格式的新文档。
use office_oxide::create::create_from_ir;
use office_oxide::DocumentFormat;
create_from_ir(&ir, DocumentFormat::Docx, "out.docx")?;
序列化
Rust 的 DocumentIR 派生了 Serialize / Deserialize(通过 serde)。Python 的 to_ir() 返回纯 dict(已经可以 JSON 化)。Node、Go、C#、C 绑定通过 to_ir_json() / ToIRJSON() / ToIrJson() 暴露 JSON 字符串。
相关链接
- Markdown 提取 — 给 LLM 的友好文本
- HTML 提取 — 想要带样式输出时
- 转换: 旧版 → OOXML — 底层使用 IR