Skip to content

Crear documentos Office desde Markdown

create_from_markdown escribe un DOCX, XLSX o PPTX completamente nuevo a partir de una única cadena Markdown. Una fuente Markdown, tres formatos de salida. Markdown es el destino natural para el contenido generado por LLMs: haz que el modelo emita Markdown —mucho más fiable que pedirle que genere Office XML directamente— y luego materializa el formato Office adecuado bajo demanda.

Internamente, el Markdown se parsea en el DocumentIR estructurado de Office Oxide y se renderiza en el formato destino, de modo que se obtiene el mismo mapeo determinístico e independiente del formato. El IR en sí mismo es principalmente una superficie de extracción e inspección (véase to_ir()); para la creación, Markdown es el punto de entrada público en todos los bindings.

¿Cuál es la firma de create_from_markdown?

La función recibe una cadena Markdown, un formato destino ("docx", "xlsx" o "pptx", sin distinción de mayúsculas/minúsculas) y una ruta de salida. No devuelve nada en caso de éxito y lanza o devuelve un error en caso de fallo.

Binding Firma
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)

¿Cómo creo un DOCX, XLSX o PPTX desde Markdown?

Escribe el contenido una vez en Markdown y cambia el argumento format para elegir el formato destino.

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;
}

¿Cómo renderiza cada formato destino el Markdown?

El Markdown se parsea en el IR estructurado de Office Oxide y cada formato renderiza esa estructura de forma determinística:

Construcción Markdown DOCX XLSX PPTX
Encabezado # Párrafo con estilo Heading{level} Celda en negrita al inicio de una sección Marcador de posición de título de diapositiva
Texto de párrafo Párrafo de cuerpo Celdas en filas sucesivas Marcador de posición de texto del cuerpo
Lista - / 1. Lista con viñetas o numerada Celdas en la columna A Viñetas del cuerpo
Tabla Tabla de Word Celdas a partir de la siguiente fila libre Tabla de PowerPoint
**negrita** / *cursiva* Formato de texto inline Texto plano en la celda Formato de texto inline

El mapeo es conservador: cada construcción Markdown produce una salida determinística, pero cada formato Office tiene características que Markdown no modela (formatos de número de celda en XLSX, animaciones en PPTX, hilos de comentarios en DOCX). Para una salida más rica, crea el archivo y luego edítalo con el editor específico del formato, o usa los escritores específicos de formato.

¿Cómo leer, modificar y escribir de vuelta entre formatos?

Combina extracción y creación para hacer ediciones de contenido que funcionen entre formatos. Lee la fuente como Markdown, modifica el Markdown y escribe un nuevo archivo:

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;
}

Este es también un camino limpio para la modernización de legado → OOXML (DOC → DOCX, XLS → XLSX, PPT → PPTX) cuando solo se necesita la estructura textual. Para una conversión que preserve la estructura manteniendo el layout original, usa save_as(), que hace el viaje de ida y vuelta a través del IR. Véase Conversión: legado → OOXML.

¿Por qué generar archivos Office desde Markdown?

  • Plantillas independientes del formato. Genera el mismo contenido como DOCX (para usuarios de Word), XLSX (para analistas) o PPTX (para presentaciones) sin reescribir nada — solo cambia el argumento format.
  • Nativo para LLMs. Haz que el modelo produzca Markdown y materializa el archivo. Markdown es lo que los modelos emiten con más fiabilidad.
  • Con soporte para diffs. Markdown es texto plano; confírmalo. El archivo Office se convierte en un artefacto de construcción.
  • Rápido. El núcleo Rust de Office Oxide escribe archivos en milisegundos, con una tasa de aprobación del 100% en el corpus de benchmarks.

Avanzado: construir directamente desde un DocumentIR (Rust)

El crate de Rust además expone create_from_ir para quienes quieran construir o transformar el IR estructurado a mano en lugar de pasar por 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<()>

En los bindings de Python, Go, JavaScript y C#, el IR es de solo lectura — obtenlo con to_ir() para inspección y pipelines, y crea archivos con create_from_markdown.

Limitaciones

  • El formato de celdas (formatos de número, moneda, estilos personalizados) no se puede expresar en Markdown. Añádelo mediante el editor específico del formato después de la creación.
  • Las imágenes, gráficos, SmartArt y objetos incrustados no se transportan por la ruta Markdown — usa los escritores específicos de formato (XlsxWriter, PptxWriter o el builder DOCX) para eso.
  • Las combinaciones de celdas en XLSX, las animaciones en PPTX y los hilos de comentarios en DOCX no tienen equivalente en Markdown.

Para todo lo que esté más allá del rango expresivo de Markdown, usa los escritores específicos de formato. Ofrecen acceso completo a las características de OOXML a costa de ser específicos del formato.

Preguntas frecuentes

¿Qué formatos puede producir create_from_markdown? DOCX, XLSX y PPTX. El argumento format es "docx", "xlsx" o "pptx" (sin distinción de mayúsculas/minúsculas). Los formatos binarios heredados (DOC, XLS, PPT) son de solo lectura y no se pueden crear.

¿Hay una función create_from_ir en Python u otros bindings? No. create_from_ir solo está disponible en el crate de Rust. En Python, Go, JavaScript y C#, crea archivos con create_from_markdown; el IR (to_ir/to_ir_json) es un concepto de solo lectura del lado de la extracción.

¿Cómo hago un viaje de ida y vuelta por un documento existente manteniendo su layout? Usa save_as() para una conversión que preserve la estructura. Usa to_markdown() + create_from_markdown() cuando solo necesites reconstruir la estructura textual de forma limpia.

¿Qué tan rápida es la creación de documentos? El núcleo Rust de Office Oxide escribe archivos Office en milisegundos, con una tasa de aprobación del 100% en el corpus de benchmarks — suficientemente rápido para generar documentos bajo demanda dentro de un manejador de solicitudes.

Ver también