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
.

Ahora instala la librería con:
composer require phpoffice/phpword

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.
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
Si tiene consultas puede hacérmelas llegar en https://parzibyte.me/#contacto
Saludos!
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.
Hola, PHPWord es compatible con PHP 7? porque he visto que se han presentado algunos comentarios al respecto, saludos
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
Yo lo estoy trabajando con PHP7 hasta el momento no he tenido problemas
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
]);
Me pasa exactamente lo mismo. Es muy frustrante porque todos parecen tener solucionado el problema.
muchas gracias, ya le entendí un poco mejor a esto, porque con el manual no pude, por otro lado tendrás tutoriales sobre phpword en cuanto a encabezados y pies de pagina?, gracias
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?
Simplemente indica en el encabezado el nombre del archivo. Por ejemplo:
header(‘Content-Disposition: attachment;filename=”‘ . $nombreDelDocumento . ‘”‘);
Tengo un ejemplo con Excel:
https://parzibyte.me/blog/2018/11/08/crear-archivo-excel-php-phpspreadsheet/
Saludos
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);
Faltan más encabezados, además de que no debes invocar a saveAs. Al menos en Excel se hace con:
$writer->save(‘php://output’);
Por favor, lee el post que cité: https://parzibyte.me/blog/2018/11/08/crear-archivo-excel-php-phpspreadsheet/
Saludos
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;
Intenta leyendo el documento ya sea con readfile o file_get_contents. Tal vez esto te ayude: https://github.com/PHPOffice/PHPWord/issues/749
Pingback: PHP y Word: agregar listas, tablas e imágenes usando PHPWord - Parzibyte's blog