El problema

Convertir documentos de Word a PDF es una de las tareas más habituales del software de empresa. Facturas, contratos, informes, formularios de cumplimiento: nacen como archivos .docx y tienen que convertirse en PDF para compartirlos, archivarlos o imprimirlos.

Todas las soluciones existentes vienen con compromisos importantes:

  • Microsoft Office / LibreOffice — obliga a instalar una suite ofimática completa en cada servidor. El modo headless de LibreOffice es lento, consume mucha memoria y produce resultados inconsistentes entre versiones. Escalar significa levantar varias instancias que se comen gigabytes de RAM.
  • APIs en la nube (Google Docs, Adobe, CloudConvert) — añaden latencia, cuestan por conversión y envían documentos potencialmente sensibles a servidores de terceros. No es viable en sectores regulados ni en entornos aislados de la red.
  • Herramientas de HTML a PDF (wkhtmltopdf, Puppeteer) — obligan a convertir primero el DOCX a HTML, perdiendo fidelidad de formato. Las tablas, los encabezados y pies de página y los saltos de página rara vez sobreviven al viaje de ida y vuelta.

Ninguna funciona bien cuando necesitas una conversión rápida, fiel y sin conexión a escala, especialmente en pipelines automatizados, sistemas de o aplicaciones embebidas donde instalar LibreOffice no es una opción.

Cómo lo resuelve dxpdf

dxpdf es un conversor de DOCX a PDF independiente, escrito en Rust y basado en la librería gráfica Skia de Google. Lee los archivos .docx directamente, parsea la estructura OOXML y renderiza una salida PDF fiel al píxel, todo en un único binario sin más dependencias externas que Skia.

Un pipeline medir-maquetar-pintar inspirado en Flutter garantiza que el ajuste del texto, el dimensionado de las tablas y los saltos de página coincidan con lo que produce Microsoft Word:

DOCX (ZIP) → Parse → Document Model → Measure → Layout → Paint → PDF

El resultado es un conversor que tarda unos 115 ms en un documento de 3 páginas con tablas e imágenes, usando apenas 19 MB de memoria: lo bastante rápido como para ejecutarse dentro de un manejador de peticiones o procesar miles de documentos por lotes.

Qué soporta

dxpdf implementa 34 funcionalidades de OOXML con cobertura completa, entre ellas:

  • Formato de texto — negrita, cursiva, subrayado, tamaño de fuente, familia tipográfica, color, espaciado entre caracteres, superíndice, subíndice y sombreado de fragmentos
  • Párrafos — alineación (izquierda, centro, derecha), espaciado, sangría, tabulaciones, bordes y sombreado
  • Tablas — anchos de columna, márgenes de celda con cascada de 3 niveles, celdas combinadas (horizontal y vertical), alturas de fila, bordes, sombreado de celdas y tablas anidadas
  • Imágenes — en línea (PNG, JPEG, BMP, WebP) y flotantes/ancladas con alineación y posicionamiento porcentual
  • Estilos — estilos de párrafo y de carácter con herencia basedOn, valores por defecto del documento y fuentes del tema
  • Encabezados y pies de página — texto, imágenes y números de página (códigos de campo PAGE/NUMPAGES)
  • Listas — viñetas, decimal, letra minúscula/mayúscula y romana minúscula/mayúscula con seguimiento de contadores
  • Hipervínculos — renderizados como anotaciones de enlace clicables en el PDF
  • Secciones — varios tamaños de página y márgenes, saltos de sección y orientaciones vertical y horizontal
  • Maquetación — paginación automática, ajuste de línea, modos de interlineado y flujo del texto alrededor de imágenes flotantes

Tres formas de usarlo

Herramienta de línea de comandos

Instálalo y ejecútalo con un solo comando:

cargo install dxpdf
dxpdf input.docx -o output.pdf

Librería de Rust

Una llamada a función: bytes de entrada, bytes de salida.

let docx_bytes = std::fs::read("document.docx")?;
let pdf_bytes = dxpdf::convert(&docx_bytes)?;
std::fs::write("output.pdf", &pdf_bytes)?;

Para más control, inspecciona el modelo de documento parseado antes de renderizar:

use dxpdf::{parse, model};

let document = parse::parse(&std::fs::read("document.docx")?)?;

for block in &document.blocks {
    match block {
        model::Block::Paragraph(p) => { /* inspect paragraph */ }
        model::Block::Table(t) => { /* inspect table */ }
    }
}

let pdf_bytes = dxpdf::convert_document(&document)?;

Paquete de Python

Instálalo desde PyPI y úsalo en cualquier aplicación Python:

pip install dxpdf
import dxpdf

# Bytes in, bytes out
pdf_bytes = dxpdf.convert(open("input.docx", "rb").read())

# File to file
dxpdf.convert_file("input.docx", "output.pdf")

Rendimiento

Medido en un Apple M3 Max con hyperfine (20 ejecuciones, 3 de calentamiento), convirtiendo un documento de 3 páginas con 11 tablas, 2 imágenes y 2 secciones:

MétricaValor
Tiempo medio de conversión113 ms
Pico de memoria (RSS)19 MB

El núcleo en Rust tiene 104 tests unitarios y 9 tests de integración, incluidos tests de regresión visual que comparan los PDF renderizados con documentos de referencia generados por Word.

Casos de uso reales

Pipelines documentales automatizados

Sistemas de CI/CD o procesadores por lotes que generan contratos, facturas o informes a partir de plantillas .docx. dxpdf se ejecuta como un único binario: sin instalar LibreOffice, sin una imagen Docker con un entorno de escritorio completo y sin costes de API por documento.

Entornos regulados

Aplicaciones sanitarias, jurídicas y financieras donde los documentos no pueden salir de la red. dxpdf funciona completamente sin conexión y sin llamadas a servicios externos, lo que lo hace apto para despliegues aislados y on-premise.

Sistemas embebidos y edge computing

Dispositivos IoT, kioscos o contenedores ligeros donde instalar una suite ofimática de 500 MB no es práctico. Los 19 MB de memoria de dxpdf y sus tiempos de conversión por debajo del segundo lo hacen viable en entornos con recursos limitados.

Aplicaciones web en Python

Backends de Django, Flask o FastAPI que necesitan convertir archivos DOCX subidos al vuelo. Los bindings de Python envuelven el núcleo de Rust mediante PyO3, ofreciendo rendimiento nativo sin subprocesos ni servicios externos.

No. dxpdf es un conversor independiente que lee los archivos DOCX directamente y renderiza los PDF con el motor gráfico Skia de Google. No depende de ninguna suite ofimática.
dxpdf está escrito en Rust y disponible como herramienta CLI (con cargo install), librería de Rust (en crates.io) y paquete de Python (en PyPI). Funciona en macOS, Linux y Windows.
dxpdf usa un pipeline medir-maquetar-pintar inspirado en Flutter y diseñado para lograr fidelidad a nivel de píxel. Soporta 34 funcionalidades de OOXML, incluidas tablas, imágenes, encabezados y pies de página y estilos. Los tests de regresión visual comparan la salida con referencias generadas por Word.
En un Apple M3 Max, dxpdf convierte un documento de 3 páginas con tablas e imágenes en unos 113 ms con un pico de 19 MB de memoria. Es lo bastante rápido como para ejecutarse dentro de un manejador de peticiones web.
Sí. Instálalo con pip install dxpdf. El paquete de Python envuelve el núcleo de Rust mediante PyO3 y ofrece rendimiento nativo. Usa dxpdf.convert() para bytes de entrada y salida, o dxpdf.convert_file() para conversión de archivo a archivo.
Entre las funcionalidades aún no implementadas están el tachado, el resaltado de texto, las versalitas, las sombras de texto, la paginación keep-with-next, las imágenes VML, los diseños multicolumna, los encabezados de primera página, los campos de índice, las notas al pie, los comentarios, los cuadros de texto, las formas, el texto de derecha a izquierda y la partición de palabras.