Skip to content

IR에서 문서 만들기

create_from_irDocumentIR에서 처음부터 새로운 DOCX, XLSX, PPTX를 씁니다 — 즉 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: 'Quarterly Report',
    elements: [
      { kind: 'Heading', level: 1, text: 'Highlights' },
      { kind: 'Paragraph', runs: [{ text: 'Revenue grew 18%.' }] },
      { kind: 'Table', rows: [
        ['Region', 'Revenue'],
        ['NA',     '$1.2M'],
        ['EU',     '$820K'],
      ]},
    ],
  }],
};

createFromIr(ir, 'docx', 'report.docx');
createFromIr(ir, 'xlsx', 'report.xlsx');
createFromIr(ir, 'pptx', 'report.pptx');

Go

Go는 IR을 JSON 페이로드로 받습니다:

import (
    "encoding/json"
    officeoxide "github.com/yfedoseev/office_oxide/go"
)

ir := map[string]any{
    "sections": []any{
        map[string]any{
            "title": "Quarterly Report",
            "elements": []any{
                map[string]any{"kind": "Heading", "level": 1, "text": "Highlights"},
                map[string]any{"kind": "Paragraph", "runs": []any{map[string]any{"text": "Revenue grew 18%."}}},
                map[string]any{"kind": "Table", "rows": [][]string{
                    {"Region", "Revenue"},
                    {"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 = "Quarterly Report",
            elements = new object[] {
                new { kind = "Heading", level = 1, text = "Highlights" },
                new { kind = "Paragraph", runs = new[] { new { text = "Revenue grew 18%." } } },
                new { kind = "Table", rows = new[] {
                    new[] { "Region", "Revenue" },
                    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 섹션 구분 워크시트(섹션 1개 → 시트 1개) 슬라이드
Heading { level } Heading{level} 스타일 단락 행 상단의 굵은 셀 슬라이드 제목 자리표시자
Paragraph 본문 단락 연속 행의 셀 본문 텍스트 자리표시자
List { ordered, items } 번호 또는 글머리 기호 목록 A열 셀 본문 글머리 기호
Table { rows } Word 표 다음 빈 행에서 시작하는 셀 PowerPoint 표
Image { filename, data } 인라인 이미지 (스킵 — XLSX는 앵커 좌표 필요) 슬라이드 이미지

매핑은 보수적입니다: 모든 IR 요소가 결정적인 출력을 만들지만, 각 형식에는 IR이 모델링하지 않는 기능이 있습니다(XLSX 병합, PPTX 애니메이션, DOCX 코멘트 스레드). 더 풍부한 출력은 형식별 빌더를 쓰세요.

라운드트립 — 읽고, 수정하고, 쓰기

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")

이게 레거시 → OOXML 변환(DOC → DOCX, XLS → XLSX, PPT → PPTX)을 하는 가장 깔끔한 방법이기도 합니다. 변환: 레거시 → OOXML 참고.

왜 생성에 IR을 쓰는가

  • 형식 무관 템플레이트. 같은 콘텐츠를 Word 사용자용 DOCX로, 분석가용 XLSX로, 프레젠테이션용 PPTX로 다시 쓰지 않고 생성.
  • LLM 친화적. 모델이 IR 스키마에 맞는 JSON을 만들게 하고 파일로 실체화하세요. 모델에게 Office XML을 직접 뱉으라고 시키는 것보다 훨씬 안정적입니다.
  • diff 가능. IR은 JSON입니다; 커밋하세요. Office 파일은 빌드 산출물이 됩니다.

한계

  • Element::Image의 이미지는 대상 형식이 인라인 이미지를 지원할 때 쓰입니다(DOCX, PPTX). XLSX는 앵커 좌표가 필요하고, 단순 IR엔 그게 없습니다 — 스킵하거나 형식별 빌더 사용.
  • 셀 서식(숫자 포맷, 통화, 굵게)은 IR의 일부가 아닙니다. 생성 후 형식별 편집기로 추가하세요.
  • 차트, SmartArt, 임베드 객체는 IR의 일부가 아닙니다.

IR 표현력을 넘어서는 모든 것은 형식별 빌더(docx::create::DocxBuilder, xlsx::create::XlsxBuilder, pptx::create::PptxBuilder)로 들어가세요. 형식에 묶이는 대신 OOXML 기능 전체에 접근할 수 있습니다.

더 보기