Skip to content

Создание документов из 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 ценой привязки к формату.

Смотрите также