Skip to content

Створення Office-документів з Markdown

create_from_markdown створює новий DOCX, XLSX або PPTX з єдиного рядка Markdown. Одне джерело — три вихідних формати. Markdown — природній вихід для контенту, згенерованого LLM: нехай модель видає Markdown (це набагато надійніше, ніж просити її генерувати Office XML напряму), а потім перетворіть його на потрібний Office-формат на вимогу.

Усередині Markdown розбирається в структурований DocumentIR Office Oxide і рендериться у цільовий формат, що забезпечує той самий детерміністичний, незалежний від формату маппінг. IR сам по собі — це передусім поверхня для витягання й інспекції (див. to_ir()); для створення документів публічна точка входу в усіх байндингах — Markdown.

Яким є підпис create_from_markdown?

Функція приймає рядок Markdown, цільовий формат ("docx", "xlsx" або "pptx", регістр не важливий) та шлях виводу. У разі успіху нічого не повертає; у разі помилки кидає виняток або повертає помилку.

Байндинг Підпис
Python def create_from_markdown(markdown: str, format: str, path, /) -> None
Rust pub fn create_from_markdown(markdown: &str, format: DocumentFormat, path: impl AsRef<Path>) -> Result<()>
Go func CreateFromMarkdown(markdown, format, path string) error
JavaScript createFromMarkdown(markdown, format, path)
C# static void Document.CreateFromMarkdown(string markdown, string format, string path)

Як створити DOCX, XLSX або PPTX з Markdown?

Напишіть вміст один раз у Markdown і змінюйте аргумент format, щоб обрати цільовий формат.

Rust

use office_oxide::create::create_from_markdown;
use office_oxide::format::DocumentFormat;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let markdown = "\
# Quarterly Report

Generated automatically from Markdown using Office Oxide.

## Highlights

- Revenue grew by **32%** year-over-year
- Customer satisfaction: 4.8 / 5.0

## Financial Summary

| Category   | Q3 2025 | Q4 2025 |
|------------|---------|---------|
| Revenue    | $1.2M   | $1.6M   |
| Net Profit | $0.4M   | $0.7M   |
";

    create_from_markdown(markdown, DocumentFormat::Docx, "report.docx")?;
    create_from_markdown(markdown, DocumentFormat::Xlsx, "report.xlsx")?;
    create_from_markdown(markdown, DocumentFormat::Pptx, "report.pptx")?;
    Ok(())
}

Python

from office_oxide import create_from_markdown

markdown = """\
# Quarterly Report

Generated automatically from Markdown using Office Oxide.

## Highlights

- Revenue grew by **32%** year-over-year
- Customer satisfaction: 4.8 / 5.0
- New products launched: Widget Pro, Widget Lite

## Financial Summary

| Category   | Q3 2025 | Q4 2025 |
|------------|---------|---------|
| Revenue    | $1.2M   | $1.6M   |
| Expenses   | $0.8M   | $0.9M   |
| Net Profit | $0.4M   | $0.7M   |
"""

# One Markdown source, three target formats:
create_from_markdown(markdown, "docx", "report.docx")
create_from_markdown(markdown, "xlsx", "report.xlsx")
create_from_markdown(markdown, "pptx", "report.pptx")

JavaScript

import { createFromMarkdown } from 'office-oxide';

const markdown = `# Quarterly Report

Generated automatically from Markdown using Office Oxide.

## Highlights

- Revenue grew by **32%** year-over-year
- Customer satisfaction: 4.8 / 5.0

## Financial Summary

| Category   | Q3 2025 | Q4 2025 |
|------------|---------|---------|
| Revenue    | $1.2M   | $1.6M   |
| Net Profit | $0.4M   | $0.7M   |
`;

for (const fmt of ['docx', 'xlsx', 'pptx']) {
  createFromMarkdown(markdown, fmt, `report.${fmt}`);
}

Go

package main

import (
    "log"

    oo "github.com/yfedoseev/office_oxide/go"
)

func main() {
    markdown := `# Quarterly Report

Generated automatically from Markdown using Office Oxide.

## Highlights

- Revenue grew by **32%** year-over-year
- Customer satisfaction: 4.8 / 5.0

## Financial Summary

| Category   | Q3 2025 | Q4 2025 |
|------------|---------|---------|
| Revenue    | $1.2M   | $1.6M   |
| Net Profit | $0.4M   | $0.7M   |
`

    for _, fmt := range []string{"docx", "xlsx", "pptx"} {
        if err := oo.CreateFromMarkdown(markdown, fmt, "report."+fmt); err != nil {
            log.Fatalf("CreateFromMarkdown(%s): %v", fmt, err)
        }
    }
}

C#

using OfficeOxide;

const string markdown = """
    # Quarterly Report

    Generated automatically from Markdown using Office Oxide.

    ## Highlights

    - Revenue grew by **32%** year-over-year
    - Customer satisfaction: 4.8 / 5.0

    ## Financial Summary

    | Category   | Q3 2025 | Q4 2025 |
    |------------|---------|---------|
    | Revenue    | $1.2M   | $1.6M   |
    | Net Profit | $0.4M   | $0.7M   |
    """;

foreach (var fmt in new[] { "docx", "xlsx", "pptx" })
{
    Document.CreateFromMarkdown(markdown, fmt, $"report.{fmt}");
}

C

#include <stdio.h>
#include "office_oxide.h"

int main(void) {
    const char *markdown =
        "# Quarterly Report\n\n"
        "Generated automatically from Markdown using Office Oxide.\n\n"
        "## Highlights\n\n"
        "- Revenue grew by **32%** year-over-year\n"
        "- Customer satisfaction: 4.8 / 5.0\n\n"
        "## Financial Summary\n\n"
        "| Category   | Q3 2025 | Q4 2025 |\n"
        "|------------|---------|---------|\n"
        "| Revenue    | $1.2M   | $1.6M   |\n"
        "| Net Profit | $0.4M   | $0.7M   |\n";

    /* format: "docx" | "xlsx" | "pptx" (case-insensitive) */
    const char *formats[] = { "docx", "xlsx", "pptx" };
    for (int i = 0; i < 3; i++) {
        int err = 0;
        char path[32];
        snprintf(path, sizeof(path), "report.%s", formats[i]);
        if (office_create_from_markdown(markdown, formats[i], path, &err) != 0) {
            fprintf(stderr, "create_from_markdown(%s) failed: code=%d\n", formats[i], err);
            return 1;
        }
    }
    return 0;
}

Як Markdown рендериться в кожному цільовому форматі?

Markdown розбирається в структурований IR Office Oxide, а потім кожен формат детерміністично рендерить цю структуру:

Конструкція Markdown DOCX XLSX PPTX
Заголовок # Абзац зі стилем Heading{level} Жирна комірка на початку розділу Заповнювач заголовка слайда
Текст абзацу Текстовий абзац Комірки в послідовних рядках Заповнювач основного тексту
Список - / 1. Маркований або нумерований список Комірки в стовпці A Маркери основного тексту
Таблиця Таблиця Word Комірки починаючи з наступного вільного рядка Таблиця PowerPoint
**жирний** / *курсив* Форматування вбудованого тексту Простий текст комірки Форматування вбудованого тексту

Маппінг навмисно консервативний: кожна конструкція Markdown дає детерміністичний результат, але кожен формат Office має можливості, які Markdown не моделює (числові формати комірок XLSX, анімації PPTX, ланцюжки коментарів DOCX). Для більш насиченого виводу створіть файл і відредагуйте його в редакторі конкретного формату або скористайтеся спеціалізованими писальниками.

Як читати, змінювати та записувати назад між форматами?

Поєднуйте витягання й створення, щоб виконувати правки вмісту, які зберігаються між форматами. Читайте джерело як Markdown, вносьте зміни і записуйте новий файл:

Python

from office_oxide import Document, create_from_markdown

with Document.open("legacy.doc") as doc:
    markdown = doc.to_markdown()

# Append a new section
markdown += "\n## Appendix\n\nEffective 2026-06-22.\n"

create_from_markdown(markdown, "docx", "modernized.docx")

C

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "office_oxide.h"

int main(void) {
    int err = 0;

    /* Read the source as Markdown */
    OfficeDocumentHandle *doc = office_document_open("legacy.doc", &err);
    if (!doc) { fprintf(stderr, "open failed: code=%d\n", err); return 1; }
    char *md = office_document_to_markdown(doc, &err);
    office_document_free(doc);
    if (!md) { fprintf(stderr, "to_markdown failed: code=%d\n", err); return 1; }

    /* Append a new section */
    const char *appendix = "\n## Appendix\n\nEffective 2026-06-22.\n";
    char *modified = malloc(strlen(md) + strlen(appendix) + 1);
    strcpy(modified, md);
    strcat(modified, appendix);
    office_oxide_free_string(md);

    /* Write a fresh file */
    office_create_from_markdown(modified, "docx", "modernized.docx", &err);
    free(modified);
    return err;
}

Це також чистий шлях для модернізації застарілих форматів до OOXML (DOC → DOCX, XLS → XLSX, PPT → PPTX), коли потрібна лише текстова структура. Для конвертації зі збереженням оригінального макету використовуйте save_as(), що робить повний обіг через IR. Див. Конвертація: застарілі формати → OOXML.

Чому генерувати Office-файли з Markdown?

  • Незалежні від формату шаблони. Генеруйте той самий вміст як DOCX (для користувачів Word), XLSX (для аналітиків) або PPTX (для презентацій) без переписування — просто змінюйте аргумент format.
  • Нативно для LLM. Нехай модель видає Markdown, а ви матеріалізуєте файл. Markdown — те, що моделі генерують найнадійніше.
  • Підтримує диффи. Markdown — це звичайний текст, його можна комітити. Office-файл стає артефактом збірки.
  • Швидко. Rust-ядро Office Oxide записує файли за мілісекунди з показником проходження 100% на корпусі бенчмарків.

Для досвідчених: збірка безпосередньо з DocumentIR (Rust)

Rust-крейт додатково надає create_from_ir для тих, хто хоче вручну будувати або трансформувати структурований IR замість роботи через Markdown:

use office_oxide::create::create_from_ir;
use office_oxide::format::DocumentFormat;
use office_oxide::ir::DocumentIR;

// Build or transform a DocumentIR however you like, then render it:
let ir: DocumentIR = DocumentIR::from_markdown("# Title\n\nBody.\n", DocumentFormat::Docx);
create_from_ir(&ir, DocumentFormat::Docx, "report.docx")?;
pub fn create_from_ir(ir: &DocumentIR, format: DocumentFormat, path: impl AsRef<Path>) -> Result<()>

У байндингах Python, Go, JavaScript і C# IR доступний лише для читання — отримуйте його через to_ir() для інспекції та пайплайнів, а файли створюйте за допомогою create_from_markdown.

Обмеження

  • Форматування комірок (числові формати, валюта, власні стилі) не можна виразити в Markdown. Додавайте їх через редактор конкретного формату після створення.
  • Зображення, діаграми, SmartArt та вбудовані об’єкти не передаються через шлях Markdown — для цього використовуйте спеціалізовані писальники (XlsxWriter, PptxWriter або DOCX-будівник).
  • Об’єднання комірок XLSX, анімації PPTX та ланцюжки коментарів DOCX не мають аналогів у Markdown.

Для всього, що виходить за межі виразних можливостей Markdown, використовуйте спеціалізовані писальники для кожного формату. Вони надають повний доступ до можливостей OOXML, але прив’язані до конкретного формату.

Часті запитання

Які формати може генерувати create_from_markdown? DOCX, XLSX та PPTX. Аргумент format приймає значення "docx", "xlsx" або "pptx" (регістр не важливий). Застарілі бінарні формати (DOC, XLS, PPT) доступні лише для читання й не можуть бути створені.

Чи є функція create_from_ir у Python або інших байндингах? Ні. create_from_ir доступна лише в Rust-крейті. У Python, Go, JavaScript та C# створюйте файли за допомогою create_from_markdown; IR (to_ir/to_ir_json) — це концепція на стороні витягання, доступна лише для читання.

Як зробити повний обіг через наявний документ зі збереженням макету? Використовуйте save_as() для конвертації зі збереженням структури. Використовуйте to_markdown() + create_from_markdown(), коли потрібно чисто відновити лише текстову структуру.

Наскільки швидке створення документів? Rust-ядро Office Oxide записує Office-файли за мілісекунди з показником проходження 100% на корпусі бенчмарків — достатньо швидко, щоб генерувати документи на вимогу прямо всередині обробника запитів.

Дивіться також