Crear documentos de Word con PHP y PHPWord

Anteriormente en mi blog he escrito cómo crear y leer hojas de cálculo o documentos de Excel con PHP.

Hoy vamos a ver cómo crear documentos de Word (con extensión docx) en PHP, usando la librería PHPWord.

La librería de phpword permite varias cosas, y para comenzar veremos cómo:

  • Instalar la librería phpword usando composer (no hay pretexto para no usarlo en la actualidad)
  • Crear primer documento de Word, con propiedades, etiquetas, título, etcétera.
  • Agregar texto con distintas fuentes a documento de Word
  • Agregar títulos y alinear texto
  • Poner hipervínculos dentro de un documento de Word
  • Agregar saltos de línea y saltos de página
  • Guardar el documento de Word
  • Descargar el documento de Word

La librería permite más cosas, pero las veremos más tarde.

Instalar librería PHPWord

¿No has instalado Composer? aquí te digo cómo

Si ya cuentas con un proyecto, mira aquí cómo adaptarlo. En caso de que sea nuevo, inicia un proyecto con composer init.

1 – Iniciar proyecto si no existe

Ahora instala la librería con:

composer require phpoffice/phpword

2 – Instalar phpword y dependencias

Después de eso simplemente incluye el autoload:

require_once "vendor/autoload.php";

Estamos listos para comenzar.

Hola mundo con PHPWord

Para crear un documento de Word con PHP hay que crear una nueva instancia de la clase PhpOffice\PhpWord\PhpWord.

$documento = new \PhpOffice\PhpWord\PhpWord();

A ese documento se le pueden modificar las propiedades, agregar secciones, texto, imágenes, títulos, etcétera.

Para modificar las propiedades del documento hay que obtener a las mismas con $documento->getDocInfo() y luego modificarlas con métodos como setCreator, setLastModifiedBy, etcétera.

Cuando creamos el documento y lo abrimos (al menos con Microsoft Word), se abre en modo compatibilidad. Para evitarlo se utiliza:

$documento->getCompatibility()->setOoxmlVersion(15);

El idioma se establece creando una instancia de Language, la cual está en PhpOffice\PhpWord\Style\Language;

$documento->getSettings()->setThemeFontLang(new Language("ES-MX"));

En este caso le he puesto el idioma español de México.

Finalmente, para guardar el documento, se crea un escritor o writer y se llama al método save.

Como vamos a guardarlo en el disco duro, indicamos la ruta del documento de salida. Recuerda que el documento no debe estar abierto por otra aplicación durante la creación, y si ya existe, se sobrescribe.

Todo esto que explico ya no lo explicaré en los demás apartados, pero tenemos que hacerlo para establecer el idioma y guardar correctamente el documento.

Descargar documento

Si queremos forzar a su descarga a través del navegador en lugar de guardarlo dentro del disco duro hay que enviar algunos encabezados (parecidos a los que se envían con readfile) y en la ruta de salida indicar a php output:

Así tenemos dos opciones: guardarlo en el disco duro o enviarlo directamente de vuelta al usuario.

Agregar texto, hipervínculos y títulos al documento

Hasta el momento no hemos agregado contenido al documento, pero fue porque estaba explicando cómo es que funcionan las propiedades, el idioma y esas cosas.

Para agregar contenido se debe comenzar agregando una sección con:

$seccion = $documento->addSection();

Y a la sección se le puede agregar texto con addText. Esta función puede tomar varios parámetros pero aquí vemos dos (solo el primero es opcional), el texto y una fuente.

La fuente está representada por un arreglo que puede ser declarado con array o con [] usando la sintaxis corta.

También se puede agregar un hipervínculo con addLink($link, $titulo, $fuente).

Los títulos se agregan con addTitle($titulo, $profundidad) en donde la profundidad indica, si lo queremos ver así, el número de título. Por ejemplo, un subtítulo sería un título con profundidad de 2.

Para agregar estilos de títulos (y así todos los títulos con esa profundidad los tendrán) se llama al método addTitleStyle($profundidad, $fuente)

El código de arriba habrá generado un documento como el que se ve aquí.

Nota: los colores están especificados en hexadecimal.

Texto con estilo, textrun

Para agregar texto con distintos formatos (incluso imágenes) en el mismo párrafo y para alinear al mismo, se debe crear un textRun con addTextRun pasando como argumento el estilo de ese párrafo.

En este caso el alignment es en Jc::BOTH para que sea lo mismo que justify o justificado, la constante se encuentra en PhpOffice\PhpWord\SimpleType\Jc por eso se indica su uso al inicio.

El valor de lineHeight es la separación de líneas, entre mayor sea, más separación habrá.

Cuando tenemos el textRun se puede agregar texto normalmente, con addText, pasando una fuente personalizada si se desea.

Cada llamada a addText es como una concatenación, es decir, no se crea un nuevo párrafo, sino que se agrega.

También se pueden agregar saltos con addTextBreak, y claramente se pueden agregar los textRun que se necesiten, no hay límite.

Gracias al textRun se pueden agregar párrafos de texto en donde haya distintas fuentes y estilos.

El resultado del ejemplo se puede ver aquí. Y si te lo preguntas, el texto es de un post de un sistema de cotizaciones.

Saltos de línea y saltos de página

Para terminar este post (habrá todavía más) veamos cómo agregar separaciones entre párrafos o entre páginas.

Si queremos agregar un salto de línea lo hacemos con $seccion->addTextBreak() indicando el número de saltos.

Para agregar un salto de página llamamos a $seccion->addPageBreak(), podemos hacerlo dentro de un ciclo en caso de querer saltar muchas veces.

El documento creado se puede ver aquí.

Conclusión

Esta es la parte 1 de 3, en el siguiente post veremos cómo crear listas, tablas y agregar imágenes ya sea locales o de internet.

Por cierto, la documentación oficial está aquí.

Actualización: ya está aquí la parte 2.

Encantado de ayudarte


Estoy disponible para trabajar en tu proyecto, modificar el programa del post o realizar tu tarea pendiente, no dudes en ponerte en contacto conmigo.

No te pierdas ninguno de mis posts

Suscríbete a mi canal de Telegram para recibir una notificación cuando escriba un nuevo tutorial de programación.

16 comentarios en “Crear documentos de Word con PHP y PHPWord”

  1. Como podría establecer mi reporte en una sola hoja de Word tengo encabezados y pie de pagina, además de una tabla de datos extraída desde MySQL con php, pero me los muestra en hojas separadas, una hoja para encabezado, una hoja para mi tabla, y una mas para el pie de pagina, Saludos

  2. Buenas. He estado trabajando con esta clase para generar documentos Word y me ha resultado muy interesante. El único problema es que no he podido solucionar un problema que tengo con el alineado de los textos y los estilos. He seguido los ejemplos al pie de la letra y si bien no tengo errores no obtengo los resultados que necesito.

    Por otro lado si bien puedo generar documentos de Open Office y PDFs sin problemas el maquetado y los estilos no son los mismos, incluso he perdido elementos en la conversión.

    Es muy frustrante porque PHP Office parecía tener todas las respuestas a mis problemas y no he podido implementarlo correctamente.

    ¿Alguien ha tenido problemas similares?
    Saludos.

    1. Hola. Me parece que lo he probado con esa versión y no he tenido problemas. Para asegurarse puede probarlo por usted mismo; estoy seguro de que funcionará correctamente
      Saludos 🙂

  3. buenas como lo puedo hacer para poner un titulo en el medio… como si fuera un text aling : center?? No me funciona…… lo hago de esta manera i nada…..

    $seccion = $documento->addSection();
    # Títulos. Solo modificando depth (el número)
    $fuenteTitulo = [
    “name” => “Arial”,
    “size” => 14,
    “color” => “000000”,
    ];
    $documento->addTitleStyle(1, $fuenteTitulo);
    $seccion->addTitle(“Regidora de Benestar Social”, 1);
    $documento->addTitleStyle(2, $fuenteTitulo);
    $seccion->addTitle(“INFORME PRESTACIÓ ECONÒMICA”, 2);
    $textRun = $seccion->addTextRun([
    “alignment” => Jc::CENTER,
    // ‘textAlign’ => ‘center’,
    // “lineHeight” => 1, # Quedará muy pegado
    ]);

  4. Excelente tutorial…
    yo tengo este codigo, me genera un word a partir de una plantilla…
    ——————————————-
    require_once “vendor/autoload.php”;
    $templateProcessor = new \PhpOffice\PhpWord\TemplateProcessor(‘Template.docx’);
    $templateProcessor->setValue(‘date’, date(“d-m-Y”));
    $templateProcessor->setValue(‘name’, ‘John Doe’);
    $templateProcessor->setValue(
    [‘city’, ‘street’],
    [‘Sunnydale, 54321 Wisconsin’, ‘123 International Lane’]);
    $templateProcessor->saveAs(‘MyWordFile.docx’);
    —————————————————————–
    me gustaria saber como hacer 2 cosas…
    Que lo descargue preguntando donde debe ir y que al guardar, lo guarden con el nombre de la persona ejemplo: John Doe.docx

    seria posible que me ayudara en eso?

    1. Si lo intente ;setValue(‘date’, date(“d-m-Y”));
      $templateProcessor->setValue(‘name’, ‘John Doe’);
      $templateProcessor->setValue(
      [‘city’, ‘street’],
      [‘Sunnydale, 54321 Wisconsin’, ‘123 International Lane’]);
      $nombreDelDocumento = “Jhon Doe.docx”;
      header(‘Content-Disposition: attachment; filename=”‘.$nombreDelDocumento.'”‘);

      $templateProcessor->saveAs($nombreDelDocumento);

    2. al final no me resulto, creo que no se puede trabajando con una plantilla… solo haciendo desde el documento.

      asi quedo el codigo:
      setValue(‘date’, date(“d-m-Y”));
      $templateProcessor->setValue(‘name’, ‘John Doe 2’);
      $templateProcessor->setValue(
      [‘city’, ‘street’],
      [‘Sunnydale, 54321 Wisconsin’, ‘123 International Lane’]);
      $nombreDelDocumento = “Jhon Doe.docx”;
      header(“Content-Description: File Transfer”);
      header(‘Content-Disposition: attachment; filename=”‘ . $nombreDelDocumento . ‘”‘);
      header(‘Content-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document’);
      header(‘Content-Transfer-Encoding: binary’);
      header(‘Cache-Control: must-revalidate, post-check=0, pre-check=0’);
      header(‘Expires: 0’);

      $writer = IOFactory::createWriter($documento, ‘docx’);
      $writer->save(‘php://output’);
      exit;

  5. Pingback: PHP y Word: agregar listas, tablas e imágenes usando PHPWord - Parzibyte's blog

Dejar un comentario