Создание документов из IR
create_from_ir пишет с нуля DOCX, XLSX или PPTX из DocumentIR — той же структурированной схемы, что вы получаете из to_ir(). Один IR, три целевых формата. IR — естественный приёмник для LLM-сгенерированного контента: пусть модель отдаёт структурированный JSON, а вы по запросу материализуете нужный Office-формат.
Собрать и записать
Rust
use office_oxide::{DocumentFormat};
use office_oxide::create::create_from_ir;
use office_oxide::ir::{DocumentIR, Section, Element, Run};
let ir = DocumentIR {
sections: vec![Section {
title: Some("Квартальный отчёт".into()),
elements: vec![
Element::Heading { level: 1, text: "Главное".into() },
Element::Paragraph { runs: vec![Run::plain("Выручка выросла на 18%.")] },
Element::Table {
rows: vec![
vec!["Регион".into(), "Выручка".into()],
vec!["NA".into(), "$1.2M".into()],
vec!["EU".into(), "$820K".into()],
],
},
],
}],
};
create_from_ir(&ir, DocumentFormat::Docx, "report.docx")?;
Меняете целевой формат — и из той же IR получаете XLSX или PPTX:
create_from_ir(&ir, DocumentFormat::Xlsx, "report.xlsx")?;
create_from_ir(&ir, DocumentFormat::Pptx, "report.pptx")?;
Python
from office_oxide import create_from_ir
ir = {
"sections": [{
"title": "Квартальный отчёт",
"elements": [
{"kind": "Heading", "level": 1, "text": "Главное"},
{"kind": "Paragraph", "runs": [{"text": "Выручка выросла на 18%."}]},
{"kind": "Table", "rows": [
["Регион", "Выручка"],
["NA", "$1.2M"],
["EU", "$820K"],
]},
],
}],
}
create_from_ir(ir, "docx", "report.docx")
create_from_ir(ir, "xlsx", "report.xlsx")
create_from_ir(ir, "pptx", "report.pptx")
JavaScript
import { createFromIr } from 'office-oxide';
const ir = {
sections: [{
title: 'Квартальный отчёт',
elements: [
{ kind: 'Heading', level: 1, text: 'Главное' },
{ kind: 'Paragraph', runs: [{ text: 'Выручка выросла на 18%.' }] },
{ kind: 'Table', rows: [
['Регион', 'Выручка'],
['NA', '$1.2M'],
['EU', '$820K'],
]},
],
}],
};
createFromIr(ir, 'docx', 'report.docx');
createFromIr(ir, 'xlsx', 'report.xlsx');
createFromIr(ir, 'pptx', 'report.pptx');
Go
В Go IR принимается как JSON-payload:
import (
"encoding/json"
officeoxide "github.com/yfedoseev/office_oxide/go"
)
ir := map[string]any{
"sections": []any{
map[string]any{
"title": "Квартальный отчёт",
"elements": []any{
map[string]any{"kind": "Heading", "level": 1, "text": "Главное"},
map[string]any{"kind": "Paragraph", "runs": []any{map[string]any{"text": "Выручка выросла на 18%."}}},
map[string]any{"kind": "Table", "rows": [][]string{
{"Регион", "Выручка"},
{"NA", "$1.2M"},
{"EU", "$820K"},
}},
},
},
},
}
payload, _ := json.Marshal(ir)
officeoxide.CreateFromIR(string(payload), "docx", "report.docx")
officeoxide.CreateFromIR(string(payload), "xlsx", "report.xlsx")
officeoxide.CreateFromIR(string(payload), "pptx", "report.pptx")
C#
using OfficeOxide;
using System.Text.Json;
var ir = new {
sections = new[] {
new {
title = "Квартальный отчёт",
elements = new object[] {
new { kind = "Heading", level = 1, text = "Главное" },
new { kind = "Paragraph", runs = new[] { new { text = "Выручка выросла на 18%." } } },
new { kind = "Table", rows = new[] {
new[] { "Регион", "Выручка" },
new[] { "NA", "$1.2M" },
new[] { "EU", "$820K" },
}},
},
},
},
};
var payload = JsonSerializer.Serialize(ir);
OfficeOxide.CreateFromIr(payload, "docx", "report.docx");
OfficeOxide.CreateFromIr(payload, "xlsx", "report.xlsx");
OfficeOxide.CreateFromIr(payload, "pptx", "report.pptx");
Как каждый целевой формат рендерит IR
| Элемент IR | DOCX | XLSX | PPTX |
|---|---|---|---|
Section |
Разрыв раздела Word | Worksheet (одна section → один лист) | Слайд |
Heading { level } |
Параграф со стилем Heading{level} |
Жирная ячейка в первой строке | Плейсхолдер заголовка слайда |
Paragraph |
Body-параграф | Ячейки в последовательных строках | Плейсхолдер body-текста |
List { ordered, items } |
Нумерованный/маркированный список | Ячейки в столбце A | Маркеры body-текста |
Table { rows } |
Таблица Word | Ячейки начиная со следующей свободной строки | Таблица PowerPoint |
Image { filename, data } |
Inline-изображение | (пропускается — XLSX нужны координаты якоря) | Изображение слайда |
Маппинг консервативный: каждый IR-элемент даёт детерминированный вывод, но у каждого формата есть фичи, которые IR не моделирует (merges в XLSX, анимации в PPTX, треды комментариев в DOCX). За богатый вывод — в формат-специфичные билдеры.
Round-trip — прочитать, изменить, записать
Сочетание to_ir() и create_from_ir даёт структурные правки, которые переживают смену формата:
from office_oxide import Document, create_from_ir
with Document.open("legacy.doc") as doc:
ir = doc.to_ir()
# Добавляем новую секцию
ir["sections"].append({
"title": "Приложение",
"elements": [
{"kind": "Heading", "level": 2, "text": "Обновлённые условия"},
{"kind": "Paragraph", "runs": [{"text": "В силе с 2026-04-19."}]},
],
})
create_from_ir(ir, "docx", "modernized.docx")
Это же самый чистый способ конвертации legacy → OOXML (DOC → DOCX, XLS → XLSX, PPT → PPTX). См. Конвертация: legacy → OOXML.
Зачем использовать IR для создания
- Формат-агностичные шаблоны. Сгенерируйте один и тот же контент как DOCX (для Word-юзеров), XLSX (для аналитиков) или PPTX (для презентаций) без переписывания.
- LLM-нейтрально. Просите модель выдавать JSON по схеме IR — и материализуйте файл. Гораздо надёжнее, чем заставлять её эмитить Office XML напрямую.
- Diffable. IR — это JSON; коммитьте его. Office-файл становится артефактом сборки.
Ограничения
- Изображения в
Element::Imageпишутся, когда целевой формат поддерживает inline-картинки (DOCX, PPTX). Для XLSX нужны координаты якоря, которых в простом IR нет — пропускайте или используйте формат-специфичный билдер. - Форматирование ячеек (числовые форматы, валюта, жирный) — не часть IR. Добавляйте через формат-специфичный редактор после создания.
- Графики, SmartArt и embedded-объекты — не часть IR.
Для всего, что выходит за выразительность IR, переходите на формат-специфичные билдеры (docx::create::DocxBuilder, xlsx::create::XlsxBuilder, pptx::create::PptxBuilder). Они дают полный доступ к фичам OOXML ценой привязки к формату.
Смотрите также
- Структурированный IR — схема в деталях
- Конвертация: legacy → OOXML — под капотом использует
create_from_ir - Обзор редактирования — изменять существующие файлы на месте