Crear documentos word (doc, docx) con PHPWord y TemplateProcesor





   Por necesidades en mi trabajo he tenido que recurrir a una librería para crear documentos word. Esta librería se llama PHPWord y está escrita en php. La versión actual soporta Microsoft Office Open XML (OOXML or OpenXML), OASIS Open Document Format for Office Applications (OpenDocument or ODF), Rich Text Format (RTF), HTML, y PDF.

   Podéis descargarla del repositorio en GiHub, y los requisitos mínimos son:
  • PHP 5.3 superior.
  • Extensiones zip y xml parser.
  • Opcionales: XMLWriter (para .docx y .odt), XSL (estilos plantillas), GD (para añadir imágenes) y dompdf (para PDF).

INSTALACIÓN

   En el repositorio viene como instalar la libreria pero os lo pongo aqui también.
   Recomiendan instalarla a través de composer, incluyendo un pequeño código en el fichero composer.json:

{
    "require": {
       "phpoffice/phpword": "dev-master"
    }
} 

   La otra forma es descargarse todos los ficheros de la libreria y ponerlos en nuestro proyecto. Después en nuestro fichero .php tenemos que registrar el autoloader. Esto se hace poniendo las siguientes líneas en nuestro fichero:

require_once 'carpetaPHPWord/src/PhpWord/Autoloader.php';
\PhpOffice\PhpWord\Autoloader::register();

CREAR DOCUMENTO

   En esta primera parte vamos a crear un nuevo documento word con PHPWord. Después de incluir las líneas anteriores en nuestro fichero .php encargado de generar el documento, tenemos que incluir lo siguiente:

use PhpOffice\PhpWord\PhpWord;
use PhpOffice\PhpWord\Style\Font;

   A continuación hacemos la instancia de la clase. La podemos hacer de dos formas:

$documento = new PhpWord();

   o

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

   Ahora ya podemos añadir elementos a nuestro documento. Tenemos que crear una sección, que luego se añadirá al documento.


$seccion = $documento->addSection();

   A la sección podemos añadirle los elementos que queramos.

- Texto:

// Texto sin formato
$seccion->addText(
 htmlspecialchars(
  'Primer texto - Texto sin formato'
 )
);

// Texto con formato
$seccion->addText(
htmlspecialchars(
'Segundo texto con formato'
),
array('name' => 'Arial', 'size' => '12', 'bold' => 'true')
);


// Texto con fuente personalizada
$fuente_propia = 'mifuente';
$documento->addFontStyle($fuente_propia,
array('name' => 'Arial', 'size' => '14', 'bold' => 'true', 'color' => '5882FA')
);

$seccion->addText(
htmlspecialchars(
'Tercer texto con formato'
),
$fuente_propia
);

// Texto con objetos
$fuente = new Font();
$fuente->setBold(true);
$fuente->setName('Tahoma');
$fuente->setSize(16);
$fuente->setColor('9F81F7');
$texto = $seccion->addText(htmlspecialchars(
'Cuarto texto con formato'
));
$texto->setFontStyle($fuente);

-Tabla:

// Tabla personalizada
$estilo_tabla = array(
'borderColor' => 'F2F2F2',
'borderSize' => '5',
'cellMargin' => '20',
'bgColor' => '088A68',
);

$primera_fila = array('bgColor' => 'F2F2F2');
$documento->addTableStyle('mitabla',$estilo_tabla, $primera_fila);
$tabla = $seccion->addTable('mitabla');

for ($row = 1; $row <= 8; $row++) {
    $tabla->addRow();
    for ($cell = 1; $cell <= 3; $cell++) {
    if($row ==1)
    $tabla->addCell(200)->addText(htmlspecialchars('primera'));
    else
        $tabla->addCell(200)->addText(htmlspecialchars('celda'));
    }
}

-Salto:

$seccion->addTextBreak(1);

-Imagenes:

$seccion->addImage(
    'imagen.jpg',
    array(
        'width' => 600,
        'height' => 400,
        'wrappingStyle' => 'behind'
    )
);

   Estos son solo dos ejemplos. Podemos dar estilos, pie de página y muchas cosas más. Podéis consultar el siguiente enlace


   Por último para guardar el documento en docx, pdf o html lo hacemos de la siguiente forma:

$objWriter = \PhpOffice\PhpWord\IOFactory::createWriter($documento, 'Word2007');
$objWriter->save('Documento1.docx');

$objWriter = \PhpOffice\PhpWord\IOFactory::createWriter($documento, 'ODText');
$objWriter->save('Documento1.odt');

$objWriter = \PhpOffice\PhpWord\IOFactory::createWriter($documento, 'HTML');
$objWriter->save('Documento1.html');

LEER DOCUMENTO (PLANTILLA) Y ASIGNAR TEXTO.

   En este apartado tenemos que tener una plantilla en word. En esta plantilla tenemos que poner los valores que queramos que sean sustituidos de una determinada forma:

${valor}


   Cuando tengamos la plantilla hecha, para leerla y sustituir los datos lo haremos de la siguiente manera en php:

        $templateWord = new TemplateProcessor('plantilla.docx');

        // --- Variables
       
        $nombre = "Sandra S.L.";
        $direccion = "Mi dirección";
        $municipio = "Mrd";
        $provincia = "Bdj";
        $cp = "02541";
        $telefono = "24536784";

        // --- Asignamos valores
        $templateWord->setValue('nombre_empresa', $nombre);
        $templateWord->setValue('direccion_empresa', $direccion);
        $templateWord->setValue('municipio_empresa', $municipio);
        $templateWord->setValue('provincia_empresa', $provincia);
        $templateWord->setValue('cp_empresa', $cp);
        $templateWord->setValue('telefono_empresa', $telefono);

        // --- Guardamos el documento
        $templateWord->saveAs('Documento02.docx');
       
   También podemos poner para que se descargue directamente (también válido para el apartado anterior):

        header("Content-Disposition: attachment; filename=Documento02.docx; charset=iso-8859-1");
        echo file_get_contents('Documento02.docx');


   Podéis descargaros el PROYECTO para ver los ejemplos.

257 comentarios: Deja tu comentario

  1. Requiero hacer una carta con datos de una base de datos de mysql , tienes un ejemplo no se como ?

    ResponderEliminar
    Respuestas
    1. Tienes que utilizar una plantilla. Te creas un documento word que actue como plantilla. En él escribes la carta y los valores que quieras sustituir por los de la base de datos lo tienes que poner de la siguiente forma: ${valor1}.
      Cuando tengas la plantilla hecha, ahora desde php tienes que leerla y sustituir esos valores por los de la base de datos. Creas el conector de la base de datos y realizas la consulta que sea (no sé si lo que preguntas es esto). Te devolvera los valores y estos son los que sustituyes:

      $templateWord = new TemplateProcessor('plantilla.docx');

      $datosBD = funcionLeerDatosBD();

      $templateWord->setValue('valor1', $datosBD->valor1);
      $templateWord->setValue('valor2', $datosBD->valor2);

      $templateWord->saveAs('Documento02.docx');

      Es como en el segundo video que tengo pero la diferencia es que lees los datos de una base de datos en vez de asignarlos directamente.

      Yo para conectarme a la BD uso:

      $link =new mysqli($host,$usuario,$password,$bd);
      if (mysqli_connect_error())
      throw new Exception('ERROR - '.__METHOD__.' : No conecta con la BD => '.mysqli_connect_error());

      Y para una consulta:

      $query = "select * from .....";
      $query = $link->query($QAux)
      $resultado=$query->fetch_object(); // bucle si son varios
      $query->close();

      Y la plantilla pues no se, puede ser algo tal que así:

      En ${ciudad} a ${fecha}

      Estimado ${nombre_envio}:

      Escribo para comunicarle las personas presentes en el seminario. La lista es la siguiente:
      - ${persona1}
      - ${persona2}
      - ${persona3}
      .
      .
      .

      Atentamente,
      ${mi_nombre}

      No sé algo así jajaj

      Eliminar
    2. eres un amor.. mil gracias. Lo estoy intentando ;) gracias de nuevo. Empiezo a comprender

      Eliminar
    3. no me funciona :( . Que estoy haciendo mal , te agradezco tu asesoría

      copio el codigo de una copia de tu ejemplo que llame

      template2.php


      '.mysqli_connect_error());

      // --- No me marca error o nada ? Al parecer no conecta


      // --- Consulta de la BD,

      $query = "SELECT DISTINCT `Tratamiento` , `NombreAgente` , `Cedula` FROM `agente` WHERE `ID-agente` =20 ";

      //$query = "select * from .....";

      $query = $link->query($QAux) // no entiendo que hace ?
      $resultado=$query->fetch_object(); // bucle si son varios ? es solo uno el `ID-agente` =20 la idea es luego poder seleccionar y hacer clic para que genere la carta

      $query->close();


      $templateWord = new TemplateProcessor('plantilla2.docx'); // esta es mi plantilla


      // --- Asignamos valores a la plantilla...si es con BD es asi ?

      $templateWord->setValue('tratamiento',$Tratamiento);
      $templateWord->setValue('nombre_agente',$NombreAgente);
      $templateWord->setValue('cedula',$Cedula);


      // --- Guardamos el documento
      $templateWord->saveAs('Documento02.docx');

      header("Content-Disposition: attachment; filename=Documento02.docx; charset=iso-8859-1");
      echo file_get_contents('Documento02.docx');

      MIl gracias


      Eliminar
    4. Hola de nuevo ^^

      $link =new mysqli($host,$usuario,$password,$bd);
      if (mysqli_connect_error())
      throw new Exception('ERROR - '.__METHOD__.' : No conecta con la BD => '.mysqli_connect_error());

      Si quieres puedes poner antes del throw un echo (echo mysqli_connect_error()). O mira algo para mostrar los errores mysql. Asegurate que has puesto bien los datos de la conexión:
      $host -> si es en local seria "localhost" sino debes poner donde tengas la BD.
      $usuario -> usuario con acceso a la base de datos.
      $password -> contraseña del usuario.
      $bd - > nombre de la base de datos.

      En esta linea me he confundido (cosas del copy-paste jeje)
      $query = $link->query($QAux) seria: $query = $link->query($query);
      lo que hace es ejecutar la sentencia, es decir el select que has puesto

      Si $resultado=$query->fetch_object(); es solo un registro despues tienes que hacer lo siguiente para ponerlo en la plantilla:

      PRIMERA FORMA:
      $templateWord->setValue('tratamiento',$resultado->Tratamiento); // son las columnas de tu resultado de la cosnulta. Recuerda que el resultado de la consulta es un objeto.
      $templateWord->setValue('nombre_agente',$resultado->NombreAgente);
      $templateWord->setValue('cedula',$resultado->Cedula);

      SEGUNDA FORMA:
      $Tratamiento=$resultado->Tratamiento;
      $NombreAgente=$resultado->NombreAgente;
      $Cedula=$resultado->Cedula;

      $templateWord->setValue('tratamiento',$Tratamiento);
      $templateWord->setValue('nombre_agente',$NombreAgente);
      $templateWord->setValue('cedula',$Cedula);

      Un saludo.

      Eliminar
  2. Hola ya e probado el código de la plantilla y si funciona perfecto pero si me podrías ayudar a introducir datos desde un formulario de php ya pase los datos con el método post pero al introducirlos en la plantilla me manda un documento php para descargar en lugar de un Word y salen muchos símbolos raros sabes como corregirlo??

    ResponderEliminar
    Respuestas
    1. Hola, gracias por comentar ^^

      Fijate si tienes bien esto:
      header("Content-Disposition: attachment; filename=Documento02.docx; charset=iso-8859-1");
      echo file_get_contents('Documento02.docx');

      Y antes de eso, cuando guardas el fichero, que tenga la extensión .docx. Y sino ponme el trozo de código para ver si te puedo ayudar.

      Un saludo.

      Eliminar
    2. los tengo correcto mira este es mi código pero aun asi me manda en lugar e un archivo word me manda un archivo php .

      setValue('folio',$folio);
      $templateWord->setValue('fecha',$fecha);
      $templateWord->setValue('solicitud',$solicitud);
      $templateWord->setValue('respuesta',$respuesta);
      $templateWord->setValue('solicitante',$nombre);

      // --- Guardamos el documento
      $templateWord->saveAs('Documento02.docx');

      header("Content-Disposition: attachment; filename=Documento02.docx; charset=iso-8859-1");
      echo file_get_contents('Documento02.docx');

      ?>

      Eliminar
    3. de antemano gracias :3 también mire que al introducir los datos estáticos desde el código funciona perfecto pero al querer hacer la introducción de datos dinamicamente mediante un formulario genera el error que te comente

      Eliminar
    4. Hola de nuevo. Tienes que tener alguna cosilla mal en el php. Me he hecho un pequeño formulario con el ejemplo y me lo descarga bien. Te lo pasó y a ver si te sirve:
      https://www.dropbox.com/s/uhuipcyy4e67x89/formulario_word.rar?dl=0

      Eliminar
  3. muchas gracias lo revisare pero crees que tenga algo que ver la recepción de los archivos porque ocupo texarea para recibir los datos porque los datos que pondré dentro de la plantilla son muí grandes me has ayudado muchísimo :3

    ResponderEliminar
    Respuestas
    1. Holaa, no creo que tenga que ver que el tamaño de la plantilla sea grande.

      Eliminar
    2. Entendido Gracias :) eres una lindura de persona :3

      Eliminar
    3. Gracias a ti por ver el post y comentar ^^

      Eliminar
  4. Se puede usar marcadores y luego setearlos segun lo que envie desde mi formulario?

    ResponderEliminar
    Respuestas
    1. No sé muy bien a lo que te refieres, pero sí puedes controlar según lo que envies del formulario y ejecutar lo que sea según el valor.

      Eliminar
  5. Una pregunta Sabes si es posible comunicar 2 formularios diferentes un formulario echo en java netbens y otro echo en php en resumen lo que quiero es poner datos en un formulario java y mandar esos datos a un formulario php !! es algo que suena muy fácil pero no encontrado la manera de como hacerlo!! de antemano gracias

    ResponderEliminar
    Respuestas
    1. Desde java cuando llames al fichero php le tienes que pasar los valores por POST o GET o el método que sea y en php si puedes leer los valores que recibes y ponerlos en el formulario php.

      Un saludo.

      Eliminar
  6. el tutorial esta increible, gracias por entregarnos tus conocmientos, queria saber si es posible generar mas de un archivo a la vez, puesto que le mando un array dentro de foreach y solo me toma el primero.

    foreach($result as $row){
    $templateWord = new TemplateProcessor($modeloCarta);
    $templateWord->setValue('dia',$ahora['mday']);
    $templateWord->setValue('mes_year', $mesYear);
    $templateWord->setValue('nombre_deudor',$row['nombre']);
    $templateWord->setValue('direccion_deudor',$row['direccion']);
    $templateWord->setValue('obligacion_deudor',$row['razSocial']);
    $templateWord->saveAs($row['nombre'].".docx");
    header("Content-Disposition: attachment; filename=".$row['nombre'].".docx; charset=iso-8859-1");
    echo file_get_contents($row['nombre'].".docx");

    }

    tendre que cerrar antes el documento, o algo por el estilo, alguna ayudita sandra :)

    ResponderEliminar
    Respuestas
    1. Hola JuanJose, me alegro que te guste y muchas gracias por comentar. El problema no está en phpWord, si te fijas en tu directorio si se te han guardado los ficheros con "saveAs", por ejemplo si comentas la línea del header y del echo puedes ver que en el directorio se guardan. El problema es en el header, ya que http no deja descargar más de un fichero por tanto sólo te descarga el primero. Para poder descargar todos tendrías que hacer algo en tu código php para comprimirlos en un archivo .zip todos los ficheros y es el archivo .zip el que descargarías en el header.

      Un saludo.

      Eliminar
  7. el ejemplo funciona perfecto muchas gracias solo tengo un problema al introducir los datos mediante un formulario con text areas al generar la plantilla no me respeta los saltos de linea (enters) pone todo el texto continuo ejemplo yo quiero que imprima así
    1
    2
    3
    4
    5
    y me imprime así
    12345
    todo continuo sabes como resolver este problema?? de antemano gracias!!

    ResponderEliminar
    Respuestas
    1. Tienes que tratar los datos del text area en php. Con la función preg_replace puedes reemplazar los saltos de línea por lo que quieras (un por ejemplo).
      http://php.net/manual/es/function.preg-replace.php

      También puedes mirar otras funciones de php.

      Eliminar
    2. me podrías ayudar con un pequeño ejemplo???

      Eliminar
    3. Un pequeño ejemplo:

      En el html tienes que tener un textarea que mandes por POST.

      El PHP:

      setValue('texto',$texto);

      // --- Guardamos el documento
      $templateWord->saveAs('Formulario.docx');
      header("Content-Disposition: attachment; filename=Formulario.docx; charset=iso-8859-1");
      echo file_get_contents('Formulario.docx');
      ?>

      Y en la plantilla pones:

      Texto: ${texto}

      Lo he probado y funciona, en el word me lo pone así:
      Texto: 1
      2
      3
      4



      Eliminar
  8. hola, espero puedas ayudarme! tu codigo esta muy bien y es justo lo que necesito pero igual debo tomar datos de una bd. modifique el codigo de templete.php de la siguiente manera:
    setValue('nombre_tipo',$nombre_tipo);
    $templateWord->setValue('marca',$marca);
    $templateWord->setValue('modelo',$modelo);
    $templateWord->setValue('n_serie',$n_serie);


    // --- Guardamos el documento
    $templateWord->saveAs('Documento02.docx');

    header("Content-Disposition: attachment; filename=Documento02.docx; charset=iso-8859-1");
    echo file_get_contents('Documento02.docx');

    ?>
    Gracias

    ResponderEliminar
  9. setValue('nombre_tipo',$nombre_tipo);
    $templateWord->setValue('marca',$marca);
    $templateWord->setValue('modelo',$modelo);
    $templateWord->setValue('n_serie',$n_serie);


    // --- Guardamos el documento
    $templateWord->saveAs('Documento02.docx');

    header("Content-Disposition: attachment; filename=Documento02.docx; charset=iso-8859-1");
    echo file_get_contents('Documento02.docx');

    ?>

    ResponderEliminar
    Respuestas
    1. Hola buenas, te contesté en el video de youtube. Te lo pongo aquí también.
      Se hace de la misma forma, lo que pasa que $nombre_tipo,$marca son datos de la base de datos. Tu haces la conexión a la base de datos, el query que sea y el resultado pues lo pones en los campos que quieras. Lo que no sé es si me preguntas por como se hace la conexión a la BD.

      Un saludo.

      Eliminar
  10. Hola, espero estes muy bien. Tengo una pequeña pregunta, como haria para agregar un foreach al documento de word. Saludos y muchas gracias por estos tutoriales

    ResponderEliminar
    Respuestas
    1. Tengo un arreglo con muchos registros de la BD, como hago para poner esos registros en el documento de word. Quedo atento, creo que no me explique con detalle en el primer comentario :D

      Eliminar
    2. Buenas,
      Simplemente haces un bucle leyendo los registros de la BD y los vas asignando a las variables que tengas para la plantilla, claro no sé como tendrás estructurada la plantillas, pero tendrás que hacerlo de la manera más apta según los datos que tengas. En comentarios anteriores hay ejemplos de la consulta a la BD.

      Un saludo.

      Eliminar
    3. SI lo de asignar las variables que vengan de la BD no es el problema, lo que no se me ocurre es como podria hacer lo siguiente:

      Foreach($array as $item){

      echo $item->objeto;
      echo $item->fechaInicio;
      echo $item->fechaFin;

      }

      Teniendo en cuenta que ese $item a veces es solo un registro y aveces podrian ser 10 o 20. Como pondría eso en la plantilla de word. Gracias por el tiempo prestado. Saludos

      Eliminar
    4. Claro, si son varios registros vas a estar sobreescribiendo la misma variable de la plantilla. Hay una función en la libreria para clonar los valores antes de hacer el setValue. He encontrado un documento que lo explica super bien y te viene un ejemplo (está en inglés):
      http://jeroen.is/phpword-templates-with-repeating-rows/

      Eliminar
  11. Hola, estoy tratando leer una plantilla tal como lo pones en el tutorial, pero no se si debo instalar algo del TemplateProcessor o viene incluido con la libreria PHPWord, basicamente lo que quiero hacer es leer una plantilla de un formato para control de documentos iso y llenarlo con informacion de una bd. Me marca este error. Class 'TemplateProcessor' not found in /opt/lampp/htdocs/intranet/application/libraries/isoword.php

    ResponderEliminar
    Respuestas
    1. Tienes mal la llamada a la ruta hacia la librería de PHPWord porque si te fijas se te queda en libraries/isoword.php y debería de venir al menos libraries/PHPWord-master/....
      Porque por lo que veo en tu llamada no estás accediendo a la librería y por eso dice que te falta ese archivo, porque no está en esa ruta.
      También tienes que descargarte la libreria y copiar todos los archivos tal y como están, como en el otro tutorial o este video:
      https://www.youtube.com/watch?v=ABsk2ajYAGQ

      Eliminar
    2. Muchisimas gracias, ya lo solucione, ahora me he topado con un detalle, la informacion que tengo que pasarle desde la bd como variables viene con algunas etiquetas html, mismas que necesito que se interpreten y me genere el documento con ese formato, por ejemplo listas o negritas, con esta opcion del TemplateProcessor si puedo hacer eso?

      Eliminar
    3. Lo que se es que a la hora de hacer la plantilla tu los campos que quieras de los datos los puedes poner en negrita, color o lo que sea, y los datos que se carguen ahi se cargaran con esa configuración.

      Eliminar
  12. ME SALE ERROR : Parse error: syntax error, unexpected 'use' (T_USE) FAVOR AYUDA

    ResponderEliminar
    Respuestas
    1. Qué tienes en la plantilla (la variable) y como lo estás cargando en el php

      Eliminar
  13. ME PARECE QUE ES COMO CARGO LA LIBRERIA PHPWORD

    ResponderEliminar
    Respuestas
    1. No sé si tienes problemas para cargar la libreria. Tienes que poner bien la ruta en donde están los archivos que te has descargado de la librería.
      En mi caso es esta:
      require_once 'carpetaPHPWord/src/PhpWord/Autoloader.php';
      Pero todo depende de donde pongas la carpeta.

      Eliminar
  14. Hola, necesito ayuda.. Uso TemplateProcessor para crear un documento con tabla. Esta bien. Lo tengo. Pero lo mas interesante, y no entiendo como, es como puedo marcar el TR o TC con algun color o estilo en caso si un TC tiene un valor importante?
    Perdon por mi esp.
    Gracias.

    ResponderEliminar
    Respuestas
    1. Estilos no se dan desde TemplateProcessor. Los estilos los tienes que poner en la plantilla. El campo que quieras de un color determinado pues le pones el color en word como siempre y ya está.
      Un saludo :P

      Eliminar
    2. Mira, explico lo que quiero :)
      Pues, tengo, por ejemplo, una lista de usuarios. Cada usuario tiene edad. Y quiero que cada usuario, que tiene edad mas de 50 años, sea Rojo en documento final.
      Gracias!

      Eliminar
    3. Con lo que es la plantilla (TemplateProcessor) no se puede hacer eso, solo es para cargar datos. Con lo que si se puede hacer (dar estilos y demás es creando un documento nuevo con new PhpWord().
      Pero definitivamente si lo que estás haciendo es tener una plantilla y cargar los datos creo que no se pueden dar estilos.

      Aqui tienes para dar estilos a un documento nuevo (no plantilla)
      https://github.com/PHPOffice/PHPWord

      Eliminar
    4. Aquí dice algo de aplicar una hoja de estilos pero no vienen ejemplos:

      http://phpword.readthedocs.org/en/latest/templates-processing.html

      Eliminar
    5. Oookay. Gracias. Eso ya he probado, si. Un documento nuevo - es entendido. Pero no en mi caso no nececito el nuevo. Estoy pensando en siguente dirrección:
      podemos guardar documento y leer lo con el Reader pa tener objeto $phpWord

      $fileName = $templateProcessor->save();
      $objReader = \PhpOffice\PhpWord\IOFactory::createReader('Word2007');
      $phpWord = $objReader->load($fileName);

      Así en el momento cuando hago $templateProcessor->setValue($markerName, $markerValue), puedo dejar en el $markerValue un nuevo marker para el futuro, por ejemplo:

      foreach($user as $user) {
      $templateProcessor->setValue("USER_NAME", $user->getName());
      $ageValue = $user->getAge();
      if ($user->getAge() > 50) {
      $ageValue = "\${ES_VIEJO}".$user->getAge();
      }
      $templateProcessor->setValue("USER_AGE", $ageValue);
      }

      y después cundo yo tenga $phpWord (creado con reader), tengo que buscar el texto "\${ES_VIEJO}" en no se que manera, pero creo que sea como esto:
      $phpWord->getSections()->getElements()
      y aplicar un estilo y eliminar este texto "\${ES_VIEJO}".

      Me parece real, pero depués de leer el documento y guardarlo, no encuentro allí algunos estilos de las tablas.

      Qué piensas, Sandrita?

      Eliminar
    6. La verdad que no lo he probado pero no me parece mala idea, ¿Has conseguido hacer lo que querias?

      Eliminar
    7. Oukay. Este mas o menos he hecho. Tengo nuevo documento con el Row estilizado.
      Pero...
      Alguien ha probado leer un documento con PhpOffice\PhpWord\Reader\Word2007 y guardar este objetivo con PhpOffice\PhpWord\Writer\Word2007 ?
      Es un horror..
      El documento despues de leer y guardar lo debe ser igual. Pero no es asi.
      Creo q tengo q communicarme con el autor. Además, el contributor mas activo ahi es ruso.

      Eliminar
    8. Intenta hablar con los desarrolladores/contribuidores de la libreria, a ver si te pueden dar más ideas.

      Eliminar
  15. hola Sandra, estoy usando tu ejemplo y en localhost funciona muy bien pero en mi server no, me sale el error 500 ayuda

    ResponderEliminar
    Respuestas
    1. El error 500 es un error interno del servidor. Tienes que mirar que tengas permisos de escritura en la carpeta. Mira que hayas copiado todos los archivos bien de la libreria. Revisa la ruta (de localhost al server seguramente que la ruta sea distinta, la de inclusión de la libreria). Y por último te diría que fueses depurando poco a poco a ver donde está fallando. Yo esto mismo lo subí a un servidor y tuve problemas de la carpeta de escritura al principio pero le di permisos y todo funcionaba correctamente.
      Un saludo.

      Eliminar
  16. tengo un error cuando ejecuto esta es mi consulta
    $consulta=Mandamiento::select('*')->where('mancli','=',10033548)->get();
    despues recorro es y le asigno variables a templateword

    {{
    @foreach($consulta as $consult)

    $templateWord = new TemplateProcessor('plantilla.docx');

    $templateWord->setValue('nombre_empresa',{{ $consult->mannun }});
    $templateWord->setValue('direccion_empresa',{{ $consult->mannun }});
    $templateWord->setValue('municipio_empresa',{{ $consult->mannun }});
    $templateWord->setValue('provincia_empresa',{{ $consult->mannun }});
    $templateWord->setValue('cp_empresa',{{ $consult->mannun }});
    $templateWord->setValue('telefono_empresa',{{ $consult->mannun }});

    // --- Guardamos el documento
    $templateWord->saveAs('Documento02.docx');

    header("Content-Disposition: attachment; filename=Documento02.docx; charset=iso-8859-1");
    echo file_get_contents('Documento02.docx');


    @endforeach
    }}

    y cuando ejecuto me sale error

    ResponderEliminar
    Respuestas
    1. Puedes adjuntarme el error que te sale? Es para decirte más o menos donde puede ser.

      Eliminar
  17. HOLa SALUDOS
    exelente blog, nesecito ayuda urgente sandra espero pueda ayudarme nesecito generar certificados laborales basandome en plantillas ya determinadas los datos estan devo pasarlos de exel a mysql y luego generar esos certificados desde la base de datos , la informacion es nombre cedula hay una tabla en la plantilla word esa tabla pide contrato tipo de contrato a termino y cargo cada columna tiene seis filas ej: en contrato: del 18 de enero al 26 de abril del 2010 en la fila de avajo del 19 de enero al 4 de diciembre del 2009 y asi los demas campos como lleno esa tabla con los datos de mi base de datos mysql claro los certificados en word varian tambien nesecito que se genere dependiendo de la cedula porque son certificados laborales es lo mismo que de exel a word pero nesecito realizarlo desde el servidor porque son muchas bases de datos de exel claro yo las paso al wampserver .....por favor ayudame como ingresaria esos datos al certificado y la tabla

    ResponderEliminar
    Respuestas
    1. No sé si me he enterado muy bien. Si los datos ya los tienes en mysql simplemente los lees con php y los vuelcas en las plantillas. Si tienes varias plantillas (donde están las tablas o lo que sea) pues desde php tendrás que hacerte algo para según el tipo de dato lo ponga en una plantilla u otra. Las tablas esas que dices tienen que ser plantillas. En el tutorial viene como hacer la plantilla, los campos en donde tienes que poner los valores se esciben como se indica en el tutorial; después en php asignas los valores a ese campo y te genera la plantilla.
      De excell a mysql yo no sé como se hace, se supone que eso ya lo tienes hecho.

      Un saludo.

      Eliminar
  18. la plantilla esta en word es solo que la plantilla de word a parte de que tiene texto tambien tiene una tabla donde tiene que ir el tipo de contrato y todo eso como hago para insertar datos tambien en la tabla
    HAY posivilidad de tener su correo o algo para poder ponernos en contacto y explicarle mejor de verdad que es urgente

    ResponderEliminar
    Respuestas
    1. Se hace de la misma forma para la tabla. En la tabla tendrás que poner la variable que sea, y luego en php asignar el valor a esa variable.

      Puedes agregarme a google+ y ya te paso el correo.

      https://plus.google.com/u/0/+SandraCamposSu%C3%A1rez/posts

      Eliminar
  19. with a large row number it is tooo slow to process $templateProcessor->setValue($key, $value) for each row to fill a table in the document. I've done some improvements to original TemplateProcessor to do it faster:
    http://pastebin.com/dPbkVefL

    ResponderEliminar
    Respuestas
    1. hmm, veo en github, allí ya hay algo parecido: fixBrokenMacros :)

      Eliminar
    2. sí, en github está bien, lo mismo. He probado, perfecto, funciona igual rapido.

      Eliminar
  20. podrias hacer un ejemplo utilizando laravel es que intento y no me funciona

    ResponderEliminar
    Respuestas
    1. No uso el framework de Laravel, tendría que ponerme a verlo. Pero creo que se podría hacer de la misma forma, simplemente es incluir la librería. ¿Me puedes decir si te marca un error y cuál es?

      Eliminar
  21. muy buena :) se agradece y felicitaciones por tu motivación...
    y tengo una pregunta (broma) ajkajka na descuida ;)
    saludos

    ResponderEliminar
  22. Seguimos con el salto de línea dichoso, por si alguien ha encontrado la solución.
    A ver un texto normal que almaceno en una variable o bien con str_replace, o con simplemente el nl2br logro que los saltos de línea los ponga correctamente. De hecho si lo visualizo así por ejemplo: texto_anuncio) ?> veo el resultado tal y como debe ir al word, utilizando el template.
    Pero si es con nl2br o str_replace, el word da un fallo. ¿alguien lo ha conseguido arreglar?

    ResponderEliminar
    Respuestas
    1. Arreglo un poco el por ejemplo que quería poner más arriba que con las etiquetas php no se pinto bien en el comentario anterior:

      echo nl2br($datos->texto_anuncio)

      Eliminar
    2. Holaa,

      ¿Dedónde está sacando el texto que quieres poner en la plantilla con los saltos de línea?

      Eliminar
    3. (Las etiquetas prohibidas en este comentario le inserto ***)

      La información la obtengo de unos inp***ut que recupero de una consulta a la base de datos. Lo ha realizado con Codeigniter pero supongo vale para cualquier script php. YA LO HE CONSEGUIDO, os pongo como.

      En la vista, o en el formulario con mi información, con el texto a imprimir, lo convierto a un array de la siguiente manera

      texto_anuncio);
      $texto = explode("
      ",$texto);

      $arr = $texto;
      foreach ($arr as $key => $clave) {
      //echo "Valor $key : $clave
      ";
      ?>







      y en el script que recibe esos input vía post hago:

      $extracto = $_POST["extracto_anuncio"];
      $anuncio = $_POST["texto_anuncio"];
      $anuncio0 = $_POST["texto_anuncio(0)"];
      $anuncio1 = $_POST["texto_anuncio(1)"];
      $anuncio2 = $_POST["texto_anuncio(2)"];

      $templateWord->setValue('insertar_extracto', $extracto);
      $templateWord->setValue('insertar_anuncio', htmlspecialchars($anuncio));
      $templateWord->setValue('insertar_anuncio0', htmlspecialchars($anuncio0));
      $templateWord->setValue('insertar_anuncio1', htmlspecialchars($anuncio1));
      $templateWord->setValue('insertar_anuncio2', htmlspecialchars($anuncio2));

      Funciona perfectamente. Seguramente, las variables y luego el como se pinta con setvalue, se podrán hacer con ciclos while...... pero para ser más dogmático lo dejo así.

      Gracias.

      Ya sería impresionante que esta librería permitiera trabajar con los ficheros word, editarlos, etc... y luego volver a subirlos al sitio.

      Eliminar
    4. Gracias por compartir tus conocimientos, muchas gracias.

      La verdad es que la librería podría tener muchas más cosas, sería genial. Pero bueno de momento nos vale con eso jeje.
      Un saludo.

      Eliminar
  23. Podría ingresar los datos desde un formulario! y que al darle click al botón se descargue el archivo?

    ResponderEliminar
    Respuestas
    1. Por supuesto que si. Cuando le des click mandará los datos a php y en php tienes que crear el archivo y poner lo siguiente para que se descargue directamente:

      header("Content-Disposition: attachment; filename=Documento02.docx; charset=iso-8859-1");
      echo file_get_contents('Documento02.docx');

      Eliminar
  24. hola seguí tu ejemplo pero cuando lo descargo me crea dos documentos uno en mi servidor y otro en descargas que puedo hacer para que solo me descargue uno y no ponga archivos word en el servidor con servidor me refiero a que en la carpeta donde esta el programa me pone el archivo saludos

    ResponderEliminar
    Respuestas
    1. Hola. Para que se descargue tienes que guardarlo en el servidor primero. Lo que tienes que hacer es una vez descargado borrarlo del servidor con unlink poniendo la ruta donde se guarde fichero:

      // --- borramos el fichero
      unlink('../doc/Documento01.docx');

      Eliminar
  25. Hola mil gracias por tu aporte, me podrias pprfa ayudar estoy tratando de genrear pero con datos de una base de dato de oracle, pero al hacerlo me da error y no abre mi archivo, si tienes alguna info te lo agradezco mucho te muestro como ago mi consulta.

    $sql="SELECT NOMBRES||' '||APELLIDO1 ||' '||APELLIDO2 DATOS
    FROM CONCILIACION
    WHERE NUM_SOLICITUD = XXXXX
    AND SEQ_SOLICITANTE=1";
    $query=OCI_Parse($conn,$sql);
    $ok=oci_execute($query);
    if($ok==TRUE){
    while(oci_fetch($query)){

    $solicitante=oci_result($query,"DATOS");

    }
    }
    Mil Gracias

    ResponderEliminar
    Respuestas
    1. Holaa

      ¿Te da un error en la consulta? ¿Has mirado si te devuelve bien los datos? Si todo eso está bien, ¿como pones para descargar el archivo?

      Un saludo y a ver si te puedo ayudar :P

      Eliminar
    2. Mil gracias, te confirmo la consulta en oracle la trae y imprimido la misma consulta en otro php los muestra uno de prueba, esta es la forma que lo estoy haciendo.
      require_once dirname(__FILE__).'/PHPWord-master/src/PhpWord/Autoloader.php';
      \PhpOffice\PhpWord\Autoloader::register();

      use PhpOffice\PhpWord\TemplateProcessor;

      $templateWord = new TemplateProcessor('marital.docx');

      // --- Asignamos valores a la plantilla
      $templateWord->setValue('solicitante',$solicitante);
      $templateWord->setValue('solicitatetodo',$solicitatetodo);
      $templateWord->setValue('citado',$citado);
      $templateWord->setValue('citadotodo',$citadotodo);
      $templateWord->setValue('sede',$sede);
      $templateWord->setValue('codigo',$sinproc);
      $templateWord->setValue('apoderado',$apoderado);
      $templateWord->setValue('tp',$tp);
      $templateWord->setValue('hora',$hora);
      $templateWord->setValue('solicitantecc',$solicitantecc);
      $templateWord->setValue('citadocc',$citadocc);

      // --- Guardamos el documento
      $templateWord->saveAs('Documento.docx');

      header("Content-Disposition: attachment; filename=Documento.docx; charset=iso-8859-1");
      echo file_get_contents('Documento.docx');

      Mil gracias, espero tu respuesta por si detallas el error que no e podido encontrar :D

      Eliminar
    3. Mira si la ruta de la librería está bien puesta. Mira si tienes permisos en la carpeta de escritura. ¿Me puedes poner el error que te da?

      Eliminar
  26. Las rutas esta bien, ya que si lo ejecuto sin variables de base de datos funciona y el erros abre el word y sale en mandarín jejeeejej los caracteres que aparecen no son legibles

    ResponderEliminar
    Respuestas
    1. O sea que el documento word te lo crea no? El problema es al abrir el fichero entonces. Desde donde lo abres? desde la web el que se descarga o te vas al directorio a buscarlo? :P La verdad es que es raro, nunca me pasó eso.

      Eliminar
    2. Mil gracias por tu tiempo, la verdad no se cual fue el error e eliminado todo los datos y crearlos desde cero, y pues me a funcionado diciendole que ppor defecto me abra todo en word .docx, mil gracias por tu aporte

      Eliminar
    3. Seguro que era alguna tonteria porque muchas veces pasa jeje. Me alegro de que te funciona.

      Un saludo.

      Eliminar
  27. Hola buenas tardes Sandra! Me ha servido de gran ayuda tu video, gracias!, Solo que al descargar tu proyecto de ejemplo y abrir el archivo de Word, me marca que "Existe un problema con el contenido". Tengo Office 2013 y Windows 7, quería saber si podrías ayudarme y si sepas a que se debe


    Gracias, Saludos! :)

    ResponderEliminar
    Respuestas
    1. Hola, gracias por tu comentario. No sé porque puede ser, quizás sea por la versión de office o por permisos; me he descargado el del ejemplo y claro yo lo abro sin problemas. Yo tengo el Office 2007 que es antiguo ya, así que alomejor es por eso. Un saludo.

      Eliminar
    2. muchas gracias por tu respuesta Sandra, lo intentaré con otra versión de office, saludos!

      Eliminar
    3. Holaa.
      En vez de abrir el mio, hazte una plantilla con tu office y yo creo que con eso es suficiente.
      Un saludo.

      Eliminar
  28. Hola Me sale el siguiente error

    Warning: Unexpected character in input: '\' (ASCII=92) state=1 in C:\xampp\htdocs\estudio\template_form.php on line 4

    Warning: Unexpected character in input: '\' (ASCII=92) state=1 in C:\xampp\htdocs\estudio\template_form.php on line 4

    Parse error: parse error in C:\xampp\htdocs\estudio\template_form.php on line 4

    Saludos Pablo

    ResponderEliminar
    Respuestas
    1. Tienes algún error a la hora de tratar los caracteres del input (caracteres raros como la \. ¿Puedes decir como lo estás poniendo y leyendo? un saludo.

      Eliminar
  29. Hola Sandra necesito de tu colaboración me gustaría saber si tienes un script donde guarde en pdf, gracias por su atención

    ResponderEliminar
    Respuestas
    1. Holaa, yo no lo tengo hecho. De todas formas en la página de la librería phpWord viene como hacerlo para pdf (creo que necesitas poner una librería adicional para pdf o algo así). Un saludo.

      Eliminar
  30. Disculpa me sale el siguiente error y no se como hacerle alguien me puede ayudar .....

    Fatal error: Uncaught exception 'PhpOffice\PhpWord\Exception\CreateTemporaryFileException' with message 'Could not create a temporary file with unique name in the specified directory.' in /Applications/XAMPP/xamppfiles/htdocs/formulario_word/PHPWord-master/src/PhpWord/TemplateProcessor.php:73 Stack trace: #0 /Applications/XAMPP/xamppfiles/htdocs/formulario_word/template_form.php(8): PhpOffice\PhpWord\TemplateProcessor->__construct('plantilla.docx') #1 {main} thrown in /Applications/XAMPP/xamppfiles/htdocs/formulario_word/PHPWord-master/src/PhpWord/TemplateProcessor.php on line 73

    Fatal error: Uncaught exception 'PhpOffice\PhpWord\Exception\CreateTemporaryFileException' with message 'Could not create a temporary file with unique name in the specified directory.' in /Applications/XAMPP/xamppfiles/htdocs/formulario_word/PHPWord-master/src/PhpWord/TemplateProcessor.php:73 Stack trace: #0 /Applications/XAMPP/xamppfiles/htdocs/formulario_word/template_form.php(8): PhpOffice\PhpWord\TemplateProcessor->__construct('plantilla.docx') #1 {main} thrown in /Applications/XAMPP/xamppfiles/htdocs/formulario_word/PHPWord-master/src/PhpWord/TemplateProcessor.php on line 73

    ResponderEliminar
    Respuestas
    1. Hola Betty, eso es porque tienes que dar permisos de escritura a la carpeta donde vayas a guardar los ficheros. El error te dice que no puede crear el fichero temporal. Da permisos a la carpeta que tiene todo el proyecto y listo. Un saludo.

      Eliminar
  31. Hoa Sandra.
    Disculpa pro me sale estos 3 errores:

    Warning: Unexpected character in input: '\' (ASCII=92) state=1 in C:\AppServ\www\scotyc\Formato.php on line 10

    Warning: Unexpected character in input: '\' (ASCII=92) state=1 in C:\AppServ\www\scotyc\Formato.php on line 10

    Parse error: syntax error, unexpected T_STRING in C:\AppServ\www\scotyc\Formato.php on line 10

    el sistema lo tenia en red y si salia el documento pero lo pase a localhost y ya no agarro.
    Gracias por tu tiempo.


    ResponderEliminar
    Respuestas
    1. Yo creo que ese error es porque hay caracteres que no son correctos y no los pasa bien. Intenta revisarlo. Un saludo.

      Eliminar
  32. Hola gracias por el gran aporte una pregunta? ay un directorio especifico para guardar la plantilla

    ResponderEliminar
    Respuestas
    1. No, lo puedes guardar en el directorio que tu quieras, sólo tendrás que poner las rutas bien. Un saludo.

      Eliminar
  33. Gracias por los videos! me ayudaron mucho Tengo este error:

    Warning: require_once(G:\xampp\htdocs\phpword/phpword/PHPWord-master/src/PhpWord/Autoloader.php): failed to open stream: No such file or directory in G:\xampp\htdocs\phpword\word.php on line 2

    Fatal error: require_once(): Failed opening required 'G:\xampp\htdocs\phpword/phpword/PHPWord-master/src/PhpWord/Autoloader.php' (include_path='.;G:\xampp\php\PEAR') in G:\xampp\htdocs\phpword\word.php on line 2


    Porfa me podrias decir que es lo que estoy haciendo mal....

    ResponderEliminar
    Respuestas
    1. Hola.

      Ese error es porque tienes la ruta de la librería mal puesta. Revísala para porque algo está mal :P
      Un saludo.

      Eliminar
    2. Ya lo hice ..revise todas las rutas a las librerias paso a paso.,.aunque si me funciona el programa.. pero me sale ese error y se ve feo que salga eso.al momento de descargar el word

      Eliminar
    3. Hola, pues el error es por eso, o que a la librería le falte algún archivo, o la ruta del fichero de la plantilla. El caso que el error es porque no encuentra algo en la ruta ;)

      Un saludo

      Eliminar
  34. Buenas Sandra he intentado coger tu proyecto de Plantilla de WORD y e intentado hacer lo mas sencillo cambiar el resultado de las variables del nombre de empresa para ver si me mostraba otra pero siempre me muestra Sandra S.L., ¿que puedo hacer para cambiar esto, o porque ocurre esto?
    Un saludo

    ResponderEliminar
    Respuestas
    1. Eso se debe a que todavía tienes que tener puesta la variable en la que yo pongo ese nombre:

      $nombre = "Sandra S.L.";

      Ponme el trozo de código si quieres para verlo mejor.

      Un saludo.

      Eliminar
  35. TOMAS PALACIO SANTIAGO26 de marzo de 2016, 3:29

    Hola Sandra he visto tu block y lo he estado probando y al parecer me esta funcionado pero al descargar el archivo me sale un error al momento de abrir que dice

    “Lo sentimos. No se puede abrir pruebas.docx porque existe un problema con el contenido y mas abajo dice.

    El archivo eta dañado y no se puede abrir.

    La plantilla es la misma que nos muestra pero cambie el contenido:

    Valor1: ${nombre_usuario}
    Valor2:${nit_cc}
    Valor3:${tipo_contratacion}
    Valor4:${numero_contrato}
    Valor5: $objeto
    Valor6: ${fecha_inicio}
    Valor7: ${fecha_final}
    Valor8: ${valor_contrato}
    Valor9: ${observaciones}

    Aclaro que esto lo hice con Dreamweaver, este es el código



    setValue('valor1',$datosBD->$nombre_usuario);
    $templateWord->setValue('valor2',$datosBD->$nit_cc);
    $templateWord->setValue('valor3',$datosBD->$tipo_contratacion);
    $templateWord->setValue('valor4',$datosBD->$numero_contrato);
    $templateWord->setValue('valor5',$datosBD->$objeto);
    $templateWord->setValue('valor6',$datosBD->$fecha_inicio);
    $templateWord->setValue('valor7',$datosBD->$fecha_final);
    $templateWord->setValue('valor8',$datosBD->$valor_contrato);
    $templateWord->setValue('valor9',$datosBD->$observaciones);
    //$seccion->addTextBreak(1);
    // --- Guardamos el documento
    $templateWord->saveAs('Pruebas.docx');

    header("Content-Disposition: attachment; filename=Pruebas.docx; charset=iso-8859-1");
    echo file_get_contents('Pruebas.docx');


    mysql_free_result($phpword);
    ?>

    ResponderEliminar
  36. TOMAS PALACIO SANTIAGO26 de marzo de 2016, 3:31

    Perdon este codigo no esta completo....este si....



    setValue('valor1',$datosBD->$nombre_usuario);
    $templateWord->setValue('valor2',$datosBD->$nit_cc);
    $templateWord->setValue('valor3',$datosBD->$tipo_contratacion);
    $templateWord->setValue('valor4',$datosBD->$numero_contrato);
    $templateWord->setValue('valor5',$datosBD->$objeto);
    $templateWord->setValue('valor6',$datosBD->$fecha_inicio);
    $templateWord->setValue('valor7',$datosBD->$fecha_final);
    $templateWord->setValue('valor8',$datosBD->$valor_contrato);
    $templateWord->setValue('valor9',$datosBD->$observaciones);
    //$seccion->addTextBreak(1);
    // --- Guardamos el documento
    $templateWord->saveAs('Pruebas.docx');

    header("Content-Disposition: attachment; filename=Pruebas.docx; charset=iso-8859-1");
    echo file_get_contents('Pruebas.docx');


    mysql_free_result($phpword);
    ?>

    ResponderEliminar
    Respuestas
    1. TOMAS PALACIO SANTIAGO26 de marzo de 2016, 3:45

      https://onedrive.live.com/redir?resid=8BD5C34761C5B6BD!1858&authkey=!ABiAx8waGXvDOYQ&ithint=folder%2cdocx

      Eliminar
    2. Hola. Si estás usando mi plantilla puede ser por la versión del Microsoft Office con que la hice y el tuyo. Hay a gente que le ha pasado. Prueba a crear una tuya. Si te pasa lo mismo pues lo seguimos viendo.

      Un saludo.

      Eliminar
  37. TOMAS PALACIO SANTIAGO30 de marzo de 2016, 6:42

    Hola sandra ya abrir el archivo pero no me muestra nada en la plantilla..

    $conexion=mysql_connect ("localhost","root","123456") or die("Problemas en la conexion");

    mysql_select_db("crt_sgral",$conexion)or die("Problemas en la seleccion de la base de datos");

    $sql= mysql_query ("SELECT nombre_usuario,nit_cc, tipo_contratacion, numero_contrato, objeto, fecha_inicio, fecha_final, valor_contrato, observaciones FROM sgral_crt
    where nit_cc='12535419'", $conexion) or die("Problemas en el select".mysql_error());
    //---------------------------------------------------------
    require_once dirname(__FILE__).'/PHPWord/src/PhpWord/Autoloader.php';
    \phpoffice\PhpWord\Autoloader::register();

    use PhpOffice\PhpWord\TemplateProcessor;
    /*use phpoffice\PhpWord\PhpWord;
    use phpoffice\PhpWord\Style\Font;*/

    $templateWord = new TemplateProcessor('plantilla2.docx');

    $valor1=$nombre_usuario;
    $valor2=$nit_cc;
    $valor3=$tipo_contratacion;
    $valor4=$numero_contrato;
    $valor5=$objeto;
    $valor6=$fecha_inicio;
    $valor7=$fecha_final;
    $valor8=$valor_contrato;
    $valor9=$observaciones;

    $datosBD=$sql;
    // --- Asignamos valores a la plantilla $conexion
    $templateWord->setValue('nombre_usuario',$datosBD->$$valor1);
    $templateWord->setValue('nit_cc',$datosBD->$valor2);
    $templateWord->setValue('tipo_contratacion',$datosBD->$$valor6);
    $templateWord->setValue('numero_contrato',$datosBD->$$valor4);
    $templateWord->setValue('$objeto',$datosBD->$$valor5);
    $templateWord->setValue('fecha_inicio',$datosBD->$$valor6);
    $templateWord->setValue('fecha_final',$datosBD->$$valor7);
    $templateWord->setValue('valor_contrato',$datosBD->$$valor8);
    $templateWord->setValue('observaciones',$datosBD->$$valor9);
    //$seccion->addTextBreak(1);
    // --- Guardamos el documento
    ob_clean();
    $templateWord->saveAs('Pruebas.docx');

    header("Content-Disposition: attachment; filename=Pruebas.docx; charset=iso-8859-1");
    echo file_get_contents('Pruebas.docx');
    mysql_close($conexion);

    Al abrir no me sale nada

    Valor1 ${nombre_usuario}
    Valor2 ${nit_cc}
    Valor3 ${tipo_contratacion}
    Valor4 ${numero_contrato}
    Valor5 ${objeto}
    Valor6 ${fecha_inicio}
    Valor7 ${fecha_final}
    Valor8 ${valor_contrato}
    Valor9 ${observaciones}
    ASi esta en la plantilla

    no se que hacer

    ResponderEliminar
    Respuestas
    1. Hola.

      Tienes repetido el símbolo del dolar en la asignación:

      $templateWord->setValue('nombre_usuario',$datosBD->$$valor1);
      ...

      Y luego tienes dos asignaciones distintas que en realidad no sé cual tiene el valor:

      $valor1=$nombre_usuario;
      $valor2=$nit_cc;

      y luego:
      $templateWord->setValue('nombre_usuario',$datosBD->$$valor1);
      $templateWord->setValue('nit_cc',$datosBD->$valor2);

      No sería:
      $datosBD->nombre_usuario

      O bien:
      $datosBD=$sql;
      $valor1 = $datosBD->nombre_usuario
      $templateWord->setValue('nombre_usuario',$valor1);

      Revísalo porque eso también creo que está mal.

      Un saludo.

      Eliminar
  38. Hola Sandra cómo estas? En la necesidad de pasar un reporte a Word me tope con tu página y te cuento que siguiendo los pasos publicado lo logre hacer, ahora el detalle esta es que estoy generando una factura y necesito agregar una tabla dinámica a una plantilla y aun estoy sin poder solucionar lo que ahora deseo, si tienes alguna posible solución te lo agradeceria muchisimo. Felicidades por lo publicado en tu blog referente a este tema, excelente.

    ResponderEliminar
    Respuestas
    1. Puedes hacer una plantilla y en las celdas o lo que seas pones las variables. En Php cargas los datos (que supongo que serán de una BD). Amos no sé exactamente como es tu aplicación pero claro que se puede.
      Un saludo.

      Eliminar
  39. TOMAS PALACIO SANTIAGO7 de abril de 2016, 5:08

    Hola Sandra..

    Realice los cambios que vos me dijiste, pero nada sigue igual. Segui investigando y al parece no acepta nombres largo, es decir: nombre_mio, asi de este tipo de campo, toca pegado, tambien lo hice pero no me aparece ahora nada en la plantilla al momento de llamarla y abrir..

    use PhpOffice\PhpWord\TemplateProcessor;
    /*use phpoffice\PhpWord\PhpWord;
    use phpoffice\PhpWord\Style\Font;*/

    $templateWord = new TemplateProcessor('plantilla2.docx');
    $datosBD=$sql;
    //Valores de la consulta
    //$valor1=$datosBD->nombre_usuario;
    //$valor2=$datosBD->nit_cc;
    //$valor3=$datosBD->tipo_contratacion;
    //$valor4=$datosBD->numero_contrato;
    //$valor5=$datosBD->objeto;
    //$valor6=$datosBD->fecha_inicio;
    //$valor7=$datosBD->fecha_final;
    //$valor8=$datosBD->valor_contrato;
    //$valor9=$datosBD->observaciones;
    // --- Asignamos valores a la plantilla $conexion
    $templateWord->setValue('nombreusuario',$datosBD->nombreusuario);
    $templateWord->setValue('nitcc',$datosBD->nitcc);
    $templateWord->setValue('tipocontratacion',$datosBD->tipocontratacion);
    $templateWord->setValue('numerocontrato',$datosBD->numerocontrato);
    $templateWord->setValue('objeto',$datosBD->objeto);
    $templateWord->setValue('fechainicio',$datosBD->fechainicio);
    $templateWord->setValue('fechafinal',$datosBD->fechafinal);
    $templateWord->setValue('valorcontrato',$datosBD->valorcontrato);
    $templateWord->setValue('observaciones',$datosBD->observaciones);
    //$seccion->addTextBreak(1);
    // --- Guardamos el documento
    ob_clean();
    $templateWord->saveAs('Pruebas.docx');

    header("Content-Disposition: attachment; filename=Pruebas.docx; charset=iso-8859-1");
    echo file_get_contents('Pruebas.docx');
    mysql_close($conexion);
    ?>
    Anteriormente te comente que el archivo generaba error, pense que era la version de word, lo cambie, cree uno nuevo y tampocooo solo al colocar ob_clean(); el archivo me abre. Lei en foros, asigne varios ejemplos asignando lo mismo y nada. Empece a mirar los ejemplos que trae phpword asi como este Sample_07_TemplateCloneRow.

    Ayuda por favor, si alguien le salio ayude en alguito por favor...jejej

    ResponderEliminar
    Respuestas
    1. Pues la verdad no sé que puede ser, aparentemente está todo bien. Lo único que queda es que están bien las rutas, que supongo que si lo estarán.
      Pon lo de cerrar la conexión de la BD antes de lo del header a ver si con eso...
      Un saludo.

      Eliminar
  40. Hola, con la ultima version ya no es posible realizar una instalacion manual, sabrias como hacerlo sin tener que utilizar el engorros composer? no se porque se empeñan en que tegamos que lidiar con la consola para instalar algo

    ResponderEliminar
    Respuestas
    1. Pues la verdad no he probado la última versión. Si lo pruebo lo comentaré o pongo una entrada. La verdad es que siempre hacen las cosas un tanto liosas...

      Eliminar
  41. Excelente blog Sandra, y muy buena explicación. Una consulta... tengo un template con varios textos, los mismos los tomare de una db MySql, el problema.. es que a veces tendré que completar 1 solo texto, otras veces serán 3,4 o mas textos (en el mismo template). Como hago eso? ya que no podría tener predefinidos los tags a reemplazar en el mismo porque nunca sabría cuantos textos tengo que usar. Se entiende mi consulta? gracias!

    ResponderEliminar
    Respuestas
    1. Mmmm aunque sea un poco tonto lo que se me ocurre es que tengas varias plantillas distintas y luego en php haces comprobaciones, según tengas unos textos u otros eliges que plantilla usar.
      Un saludo

      Eliminar
  42. Sera que hay alguna manera de dejar un salto de linea dentro del texto insertado en windows? lo que ocurre es que en linux si se ejecutan los saltos de linea con \n y queda bien organizada el acta, pero en windows no se ejecutan, ya he intentado con \r\n \n chr(13).chr(10) y demas, el
    como html daña el formato, si alguien tiene respuesta le agradeceria mucho

    ResponderEliminar
    Respuestas
    1. Pues la verdad no lo recuerdo no sé si a mi si me salían o no. Si lo pruebo y lo descubro te comento.
      Un saludo.

      Eliminar
  43. hola sandra primero felicitarte por tan buen trabajo, mi consulta es la siguiente como insertar una imagen a la plantilla de word??

    e intentado lo siguiente:

    $templateProcessor->setImageValue('codigo', '80173223.png', 'my-image.jpg');

    pero no me da... me puedes colaborar

    ResponderEliminar
    Respuestas
    1. No se pueden insertar imágenes si utilizas la plantilla. Si es crear un documento word con imágenes si pero si usas templateProcesor no se puede. No sé si en versiones nuevas de phpword se puede, pero en la de tutorial no.
      Un saludo.

      Eliminar
  44. HOLA!!! :D :D :D
    antes de todo muy buen tutorial me ah servido de mucho en un proyecto que tebgo para la escuela
    pero ahora necesito de tu ayuda porque tengo un problema y si me ayudas no sabria ni como agradecerte

    y es que mi duda ya antes la habias respodido en el primer comentario en un post de tu pagina
    es sobre como exportar los datos de MYSQL ala platilla la cual no logro hacer llevo un par de semanas intentando
    y nada mas ya me desespere por lo cual recurro a ti que eres la mujer de la experiencia...

    ESTE ES MI CODIGO NO SE QUE ESTOY HACIENDO MAL CUANDO DOY ENTER SI ME DESCARGA LA PLATILLA
    PERO TAL COMO ESTA SIN ALGUNA SUSTITUCION...





    setValue('ciudadano',$ciudadano);
    $templateWord->setValue('direccion',$direccion);
    $templateWord->setValue('dia',$dia);
    $templateWord->setValue('mes',$mes);
    $templateWord->setValue('año',$año);

    // --- Guardamos el documento
    $templateWord->saveAs('Documento02.docx');

    header("Content-Disposition: attachment; filename=Documento02.docx; charset=iso-8859-1");
    echo file_get_contents('Documento02.docx');

    ?>


    MUCHAS GRACIAS ESPERO PUEDAS AYUDARME o solo con ver tu codigo de la platilla con MYSQL para poder guiarme
    me serviria de mucho y te lo hubiese mandaod por correo pero pues no lo tengo x)...

    ResponderEliminar
    Respuestas
    1. Hola, muchas gracias por el comentario. Deberías de mirar en php si esas variables tienen contenido, es decir, que no estén vacías. Compruébalo con un echo. Si están vacías es que no estás haciendo bien la consulta de mysql o algo parecido. Segundo, comprueba que los nombres de los campos sean iguales en la plantilla y en php.

      Si quieres agregame a alguna de las redes sociales que están en el blog y me escribes un mensaje y te facilito el correo.
      Un saludo.

      Eliminar
  45. Hola sandra felicitaciones por tu trabajo, tengo una pregunta, como puedo manejar las etiquetas de la plantilla por ejemplo ${facturas} para que se llene una tabla dinamicamente en el archivo word cuando ya tengo el bucle en php con los todas los nuemro de facturas necesarios, pero que no todas las veces tendria el mismo numero de etiquetas ${facturas} en el word, por eso digo dinamicamente, espero haberme explicado bien. Gracias

    ResponderEliminar
    Respuestas
    1. Hola, creo que más o menos te he entendido. Con la plantilla es un poco complicado hacerlo porque lo único que se me ocurre es que en la plantilla tengas las tablas repetidas tantas veces como numero de etiquetas de facutras, y los campos los llames por ejemplo ${facturas_01}, ${facturas_02}, etc. Después en php como ya tienes el bucle, sería tener un índice y escribir en el campo facturas_indice, no se si me explico. Otra cosa no se me ocurre porque la verdad lo de la plantilla tiene muy pocas cosas en esta librería.
      Un saludo.

      Eliminar
    2. Hola Sandra, si, de hecho asi lo hice, pero pues crei que habia una forma mas apropiada para hacerlo con algun parametro, de cualquier modo muy util la libreria y tu apoyo, Mil gracias.

      Eliminar
  46. Hola Sandra de casualidad no tienes un ejemplo creando una tabla? Tengo en mi base una tabla con 2 columnas 'hallazgo y comentario' necesito poner esos 2 en una tabla pero pueden haber N registros como hago esto, gracias

    ResponderEliminar
    Respuestas
    1. He respondido un mensaje anterior a este con algo parecido. Con la plantilla es un poco difícil pero sólo se me ocurre eso. Te pongo lo que le contesté en otro comentario:

      Hola, creo que más o menos te he entendido. Con la plantilla es un poco complicado hacerlo porque lo único que se me ocurre es que en la plantilla tengas las tablas repetidas tantas veces como numero de etiquetas de facutras, y los campos los llames por ejemplo ${facturas_01}, ${facturas_02}, etc. Después en php como ya tienes el bucle, sería tener un índice y escribir en el campo facturas_indice, no se si me explico. Otra cosa no se me ocurre porque la verdad lo de la plantilla tiene muy pocas cosas en esta librería.
      Un saludo.

      Eliminar
  47. Hola Sandra, sabes si se puede obtener toda la información del archivo .doc o .docx tanto texto como imágenes, con esta biblioteca o alguna otra librería que conozcas, lo que quiero es que un usuario suba un archivo y a partir de este obtenga toda la información si es posible hasta el estilo, para después ponerlo en html. De antemano gracias, o si es posible que me comuniques con alguien mas que quizá me pueda apoyar.

    P.D. Ya encontré una librería para obtener la información, pero solo me devuelve texto plano.

    ResponderEliminar
    Respuestas
    1. Creo que te contesté ya por google, pero te lo pongo aquí por si acaso.
      Con esta librería no se obtine la información de un word (o hasta donde yo sé), lo que haces es crear un word de cero y no al revés.

      No sé si habrán metido esto con las nuevas versiones pero cuando yo lo hice no.
      Un saludo.

      Eliminar
  48. Hola! Muchas gracias por tu aporte. Quisiera saber si es posible asignar un nombre predefinido para el/los archivos generados a partir de la macro??

    ResponderEliminar
    Respuestas
    1. Desde php le puedes asignar el nombre que tu quieras a los archivos que vayas generando.

      Eliminar
  49. Hola, muchas gracias por tu aporte.
    Quisiera saber si para la forma LEER DOCUMENTO (PLANTILLA) Y ASIGNAR TEXTO. sabes como pasar un arreglo y que se despliegue como una lista en el documento??
    Saludos

    ResponderEliminar
    Respuestas
    1. Hola, se puede copiar un trozo de la plantilla y recorrer el bucle del array asignando los datos.
      En la plantilla los datos que quieras que sean una lista y quieras copiar el bloque tienen que estár dentro de las etiquetas "CLONEME" tal que así:

      ${CLONEME}
      ${variable1}
      ${variable2}
      ...
      $(/CLONEME}

      Y después con php hacer algo parecido a esto:

      $array_datos = array();
      $array_datos[0]->variable1 = "Esta es la variable 1";
      $array_datos[0]->variable2 = "Esta es la variable 2";
      $array_datos[1]->variable1 = "Esta es la variable 1 del segundo";
      $array_datos[1]->variable2 = "Esta es la variable 2 del segundo";

      $templateWord->cloneBlock('CLONEME',count($array_datos));

      $contador = 1;
      foreach ($array_datos as $datos)
      {

      $templateWord->setValue($datos->variable1, $contador);
      $templateWord->setValue($datos->variable2, $contador);
      $contador++;
      }

      Un saludo.

      Eliminar
  50. Hola buen día como puedo guradar mi plantilla en formato pdd y no en word ?

    $Archivo = "Carta"."_$NUM_CREDITO.docx";
    $Word->saveAs($Archivo);

    ResponderEliminar
    Respuestas
    1. Hola, las plantillas sólo se pueden guardar en formato doc o pdf, pdd creo que no.
      Un saludo.

      Eliminar
  51. Amigo tengo un pregunta necesito repetir los datos de una tabla intermedia, pero cuando ya tengo una plantilla lista existirá alguna manera de hacer eso

    ResponderEliminar
    Respuestas
    1. Hola, he contestado en un comentario anterior con lo siguiente, que quizás te puede valer. Es para copiar trozos de la plantilla y asignar datos como si fuesen una lista o tabla. El ejemplo es con un array pero se puede hacer lo mismo con el resultado de una consulta select.

      En la plantilla los datos que quieras que sean una lista y quieras copiar el bloque tienen que estár dentro de las etiquetas "CLONEME" tal que así:

      ${CLONEME}
      ${variable1}
      ${variable2}
      ...
      $(/CLONEME}

      Y después con php hacer algo parecido a esto:

      $array_datos = array();
      $array_datos[0]->variable1 = "Esta es la variable 1";
      $array_datos[0]->variable2 = "Esta es la variable 2";
      $array_datos[1]->variable1 = "Esta es la variable 1 del segundo";
      $array_datos[1]->variable2 = "Esta es la variable 2 del segundo";

      $templateWord->cloneBlock('CLONEME',count($array_datos));

      $contador = 1;
      foreach ($array_datos as $datos)
      {

      $templateWord->setValue($datos->variable1, $contador);
      $templateWord->setValue($datos->variable2, $contador);
      $contador++;
      }

      Eliminar
  52. HOLA, QUERIA PREGUNTAR COMO HAGO UN SALTO DE PAGINA

    ResponderEliminar
  53. Hola ante todo felicitarte por el excelente aporte que haces, quería saber si es posible generar una imagen dinámicamente dentro de una plantilla de Word, es decir, que el usuario vaya cargando una imagen quizá desde un formulario y esta sustituirla en alguna parte de la plantilla. Es esto posible? Gracias

    ResponderEliminar
    Respuestas
    1. Gracias por el comentario.
      No se pueden insertar imágenes si utilizas la plantilla. Si es crear un documento word con imágenes si pero si usas templateProcesor no se puede. No sé si en versiones nuevas de phpword se puede, pero en la de tutorial no.

      Eliminar
  54. Hola, muchas gracias por este buen tutorial.

    Cuando intento abrir el documento word generado me sale el siguiente error "word no puede abrir el documento el usuario no tiene los privilegios de acceso".
    ¿¿ Como puedo crear un archivo sin privilegios??

    ResponderEliminar
    Respuestas
    1. No sé si estás abriendo el del tutorial o uno tuyo. Suele ser por problemas de las versiones de Office.
      Un saludo.

      Eliminar
    2. Gracias por la respuesta.
      Cuando abro el tutorial me funciona bien sin ningún problema.
      Este error me sale al abrir el mio.
      Estoy usando office 2013.

      Saludos.

      Eliminar
  55. Buena tarde.

    Antes que nada muchas gracias por compartir tu conocimiento.

    En un documento que es una plantilla que ya existe, la cual abro y remplazo valores de una base de datos, hasta ahí todo excelente, pero en un anexo, debo insertar una tabla con tres columnas, las cuales pueden tener un umero de filas variable.

    Alguien sabe como se debe insertar una tabla en una plantilla ya existente?
    De antemano muchas gracias por su apoyo.

    ResponderEliminar
    Respuestas
    1. Buenas,

      Primero tienes que modificar la plantilla y poner la tabla, y en una fila tienes que indicar que es un bloque que se va a clonar y luego con php vas insertando. Puse esta explicación en un comentario, a ver si te puede servir:

      En la plantilla los datos que quieras que sean una lista y quieras copiar el bloque tienen que estár dentro de las etiquetas "CLONEME" tal que así:

      ${CLONEME}
      ${variable1}
      ${variable2}
      ...
      $(/CLONEME}

      Y después con php hacer algo parecido a esto:

      $array_datos = array();
      $array_datos[0]->variable1 = "Esta es la variable 1";
      $array_datos[0]->variable2 = "Esta es la variable 2";
      $array_datos[1]->variable1 = "Esta es la variable 1 del segundo";
      $array_datos[1]->variable2 = "Esta es la variable 2 del segundo";

      $templateWord->cloneBlock('CLONEME',count($array_datos));

      $contador = 1;
      foreach ($array_datos as $datos)
      {

      $templateWord->setValue($datos->variable1, $contador);
      $templateWord->setValue($datos->variable2, $contador);
      $contador++;
      }

      Eliminar
  56. Hola
    Se tiene la posibilidad de insertar citas y pie de páginas con esta libreria? estoy tratando de crear un documento desde cero pero teniendo la posibilidad de hacer esto...Gracias

    ResponderEliminar
    Respuestas
    1. Buenas,
      Para todas las cosas que se pueden hacer dale un vistazo a la documentación.
      http://phpword.readthedocs.io/en/latest/containers.html

      Si usas una plantilla puedes poner variables en donde quieras. Si haces un documento nuevo creo que piede páginas si se puede, citas no lo sé. Mira la documentación.
      Un saludo.

      Eliminar
  57. Buena Noche. Gracias por tu aporte, sencillo y entendible.

    Tengo una duda, asi como se leen los campos de una plantilla, se pueden leer los otros caracteres, me explico, mi intencion es buscar en un documento Word (doc o docx) una palabra clave y en caso de encontrarla extraer la pagina completa.

    "Divide y venceras"... En primer lugar necesito leer el documento (No solamente los caracteres seleccionados de la plantilla). Podrias ayudarme?

    Gracias de antemano.

    ResponderEliminar
    Respuestas
    1. Buenas, con esta librería no se puede hacer eso, por lo menos hasta donde yo sé.
      Un saludo.

      Eliminar
  58. Buenas tardes me ha gustado tu aporte por casualidad me puedes ayudar con que phpword lea un documento ms word

    ResponderEliminar
    Respuestas
    1. Con esta librería no se puede hacer esto, por lo menos hasta donde yo sé. Un saludo.

      Eliminar
  59. Amiga se que has respondido varias veces que no se puede insertar una imagen en un temple o plantilla word pero he visto este articulo https://github.com/PHPOffice/PHPWord/issues/708 me puedes explicar algo al respecto. gracias

    ResponderEliminar
    Respuestas
    1. Hola!
      Esa página lo que dice es modificar directamente la librería para poder insertar imágenes y que sólo funciona para versiones antiguas, pero amos es modificar los .php de la librería a mano, añadiendo nuevas funciones. No lo he probado.
      Un saludo.

      Eliminar
  60. Hola,

    Me podeis echar un cable ? Necesito la libreria pero me da error el tema del composer. Me podeis decir como sonseguirla por otra via o enviarmela ?

    Os lo agradeceria mucho.

    Gracias.
    Carlos

    ResponderEliminar
    Respuestas
    1. Buenas.
      No hace falta usar composer, te la puedes descargar entera y ponerla a mano. En este tutorial precisamente explico eso, sin utilizar composer. Revísalo que viene al comienzo ;)
      Un saludo!

      Eliminar
    2. ya no vale eso, en la versión v0.13.0 (31 July 2016) quitaron el fichero autoloader.php, acabo de dejar un comentario al respecto.
      ¿Sigue existiendo opción de instalarlo sin composer?
      Gracias.

      Eliminar
    3. Ahora hay otro fichero:
      require_once 'bootstrap.php';

      Pero no lo he probado.

      Eliminar
  61. Sandrita hola; sabes muy entusiasmado pero me freno no poder ejecutar ningun ejercicio. primero dsscargo el el PHPWord.php y lo p ongo en la carpeta del proyecto, vale y la primer linea de código es:
    require_once 'PHPWord.php'; y de ahi en adelante todo como lo describen pero a mi me da error ???? :-(

    ResponderEliminar
  62. Como puedo hacer para una vez creado el archivo World se abra automáticamente en alguna linea determinada del documento, alguien podría ayudarme por favor

    ResponderEliminar
    Respuestas
    1. La verdad no sé si eso se puede hacer o como se hace. Lo siento, un saludo.

      Eliminar
  63. Hola Sandra, yo no lo puedo ejecutar, lo tengo en un apache/ubuntu y al darle al template_form.php no se me descarga,
    como has instalador por composer phpword?
    gracias

    ResponderEliminar
    Respuestas
    1. Yo no lo instalé por composer, sólo hice la segunda opción, descargar los ficheros y luego poner la ruta del autoloader y tener activas las extensiones que son necesarios y vienen al principio del blog. Sé que ha cambiado la librería y ya no está el autoloader por lo que tendría que probar otra vez.

      Eliminar
  64. Hola Sandra,
    el tutorial está muy bien explicado, pero no he conseguido ni instalar la librería, porque el fichero "autoloader.php", que debería estar en la ruta que indicas para poder hacer la instalación a mano sin usar "composer":
    require_once 'carpetaPHPWord/src/PhpWord/Autoloader.php';
    YA NO EXISTE... además de haberlo comprobado físicamente (no está, por más que lo busque), en el fichero de cambios "CHAGELOG.md", he encontrado esto:
    " We also removed `\PhpOffice\PhpWord\Autoloader`, because the latter change made it completely useless.
    Autoloaders provided by Composer are in use now (see `bootstrap.php`). - @RomanSyroeshko"
    Referente a la versión v0.13.0 (31 July 2016)

    Pero en el "bootstrap.php" no veo nada...
    Si ya no hay opción de instalar el PHPWORD sin composer, podrías indicarme cómo lo hago?

    Gracias,
    Arantza.

    ResponderEliminar
    Respuestas
    1. Buenas, no he probado la nueva versión. Pero seguramente si que se puede hacer sin composer. Ahora en vez del autoloader hay que incluir la ruta al bootstrap.php.

      require_once 'bootstrap.php';

      // Creating the new document...
      $phpWord = new \PhpOffice\PhpWord\PhpWord();

      No lo he probado así que no te lo puedo asegurar. Lo tendré que probar.

      Eliminar
    2. Gracias por responder, Sandra,

      Yo voy a tener que esperar a que lo pruebes, por que a mí tampoco me funciona así.

      Este es el código del fichero más básico que debería generar un documento word con un texto tan solo:

      addSection();

      // Texto con objetos
      $fuente = new Font();
      $fuente->setBold(true);
      $fuente->setName('Tahoma');
      $fuente->setSize(16);
      $fuente->setColor('9F81F7');
      $texto = $seccion->addText(htmlspecialchars(
      'Cuarto texto con formato'
      ));
      $texto->setFontStyle($fuente);


      $objWriter = \PhpOffice\PhpWord\IOFactory::createWriter($documento, 'Word2007');
      $objWriter->save('PrimWordDoc.docx');

      $pageTitle .= 'PHPWord prueba 1';
      ?>

      los ejemplos de la carpeta "samples" tampoco me funcionan...
      Si me puedes ayudar, te lo agradezco mucho.
      Un saludo,
      Arantza.

      Eliminar
    3. No sé en qué momento me he comido un cacho de código... este es el contenido php:

      addSection();

      // Texto con objetos
      $fuente = new Font();
      $fuente->setBold(true);
      $fuente->setName('Tahoma');
      $fuente->setSize(16);
      $fuente->setColor('9F81F7');
      $texto = $seccion->addText(htmlspecialchars(
      'Cuarto texto con formato'
      ));
      $texto->setFontStyle($fuente);

      $objWriter = \PhpOffice\PhpWord\IOFactory::createWriter($documento, 'Word2007');
      $objWriter->save('PrimWordDoc.docx');

      ?>

      Eliminar
    4. vaya... pues no he sido yo quién se ha comido las líneas... faltan estas, que no sé por qué no aparecen... (a ver si ahora salen)

      require_once 'PHPWord/bootstrap.php';

      use PhpOffice\PhpWord\Settings;

      use PhpOffice\PhpWord\PhpWord;
      use PhpOffice\PhpWord\Style\Font;

      // Creating the new document...
      $documento = new \PhpOffice\PhpWord\PhpWord();

      Eliminar
    5. No he podido probar esto todavía, lo siento. Estoy liada.

      Eliminar
  65. Buenas noches, primero que nada, gracias por tu aporte, estoy realizando un contrato, y hasta ahi, todo va bien.
    Mi problema es el siguiente:
    Al final de contrato, se anexan paginas dinamicas, (una o varias paginas con logotipo y con datos que traigo de una BD) y probando no me funciona lo que propones del cloneBlock..

    Sabes como podría hacerlo, hice una prueba de la siguiente manera y no funciono, ni me duplica el bloque y tampoco me pone los campos:
    require_once dirname(__FILE__).'/PHPWord-master/src/PhpWord/Autoloader.php';
    \PhpOffice\PhpWord\Autoloader::register();

    use PhpOffice\PhpWord\TemplateProcessor;

    $templateWord = new TemplateProcessor('contrato.docx');
    $templateWord->setValue('fechacontract','February 25th 2017');
    $array_datos = array();
    $array_datos[0]->contract = "00001";
    $array_datos[0]->pricemxn_creditcard = "$2929.00";
    $array_datos[0]->cardtype = "Debit Card";
    $array_datos[1]->contract = "00002";
    $array_datos[1]->pricemxn_creditcard = "$59000.00";
    $array_datos[1]->cardtype = "Credit Card";

    $templateWord->cloneBlock('CLONEME',count($array_datos));
    $contador = 1;
    foreach ($array_datos as $datos){
    $templateWord->setValue($datos->contract, $contador);
    $templateWord->setValue($datos->pricemxn_creditcard, $contador);
    $templateWord->setValue($datos->cardtype, $contador);
    $contador++;
    }
    $templateWord->saveAs('contrato00001.docx');

    header("Content-Disposition: attachment; filename=contrato00001.docx; charset=iso-8859-1");
    echo file_get_contents('contrato00001.docx');
    unlink("contrato00001.docx");

    ***Los demas campos que agrego al cntrato como la fecha, si los pone, pero no me funciona lo del cloneBlock, sabes porque pasa?

    ResponderEliminar
  66. Excelente tu blog
    Una pregunta se puede llamar procedimientos almacenados en una plantilla

    ResponderEliminar
  67. En la plantilla puedo agregar datos de varias consultas a una base de datos. M explico mejor quiero que en la plantilla me muestre datos como resultado de varias consultas. Se puede hacer

    ResponderEliminar
    Respuestas
    1. Si claro, tienes que asignar diferentes variables en la plantilla para los diferentes datos de las consultas.

      Eliminar
  68. Hola sandra
    Me puedes dar un ejemplo de como poner en mi plantilla todos los registros que obtengo de mi consulta. Por favor con un ejemplo.

    ResponderEliminar
    Respuestas
    1. Para cada uno de los valores del resultado de una consulta tienes que crear el mismo número de variables de la plantilla y asignarlos como siempre. Un saludo.

      Eliminar
  69. Si la consulta me arroja 5000 registros , los puedo agregar a la plantilla

    ResponderEliminar
    Respuestas
    1. Hola. Ya lo he puesto en un comentario anterior.
      Tienes que hacer un bucle sobre los registros que te devuelve la consulta y cada valor asignarlo a una variable de la plantilla.

      Hay una función en la librería para clonar los valores antes de hacer el setValue. He encontrado un documento que lo explica super bien y te viene un ejemplo (está en inglés):
      http://jeroen.is/phpword-templates-with-repeating-rows/

      Eliminar
  70. Es que en la plantilla solo coloca el primer registro.

    ResponderEliminar
  71. Muchas gracias por responder Sandra, creo que lo que estoy haciendo no se puede por que igual con clonerow me tocaría luego poner 5000 etiquetas en la plantilla. hay que buscar otra forma de hacerlo para crear el documento word con PHP.

    ResponderEliminar
    Respuestas
    1. Pues la verdad no sé, no lo he hecho con tantos registros. Un saludo.

      Eliminar
  72. Buenas ingeniera cómo hago para que en una misma fila pueda poner una imagen y un texto. Por ejemplo en un encabezado que lleve el logo y un titulo. Muchas gracias por compartir sus conocimientos son de gran ayuda.

    ResponderEliminar
    Respuestas
    1. Desde php no se puede insertar una imagen si estás usando lo que es la plantilla (template procesor). Cuando editas la plantilla en word tu puedes ponerla como quieras, es un word normal.

      Eliminar
  73. Buen dia Como hago al crear un documento de word que este sea en tamaño legal, muchas gracias

    ResponderEliminar
    Respuestas
    1. Buenas, no se a que te refieres con lo de tamaño legal :P

      Eliminar
  74. el tipo de hoja en word, el predeterminado de phpword es A4 y quiero que me salga el tipo Legal. Gracias por responder

    ResponderEliminar
    Respuestas
    1. Esta es la documentación:
      http://phpword.readthedocs.io/en/latest/intro.html

      No sé si se puede hacer eso. De todas formas luego cuando lo crees, lo abres y puedes cambair el tipo de hoja desde word.

      Eliminar
  75. No he podido insertar una imagen al final del documento que se genera con una plantilla, y esta imagen no la puedo poder en la plantilla porque puede variar de acuerdo a una condición del programa. Se podrá poner una imagen al vuelo, o simplemente no se puede.

    ResponderEliminar
    Respuestas
    1. Hasta donde yo se y con la versión de phpword del tutorial, con una plantilla no se puede insertar imágenes. No sé si con la versión nueva se puede.

      Eliminar
  76. Buenas Sandra,

    Estoy intentando hacer el ejemplo que haces un tu video de crear un word mediante un plantilla pero no lo consigo en mi MAC, siempre me devuelve el error:

    Fatal error: Uncaught exception 'PhpOffice\PhpWord\Exception\CreateTemporaryFileException' with message 'Could not create a temporary file with unique name in the specified directory.'

    Le he dado permiso a todas las carpetas del XAMPP, a la carpeta de mi proyecto, pero nada no lo consigo.

    A ver si puedes ayudarme.

    Un saludo y muchas gracias!!!!

    ResponderEliminar
    Respuestas
    1. Aquí viene una solución,
      https://github.com/PHPOffice/PHPWord/issues/809

      No sólo tienes que dar permisos sino también cambiar el propietario de la carpeta temporal donde se guarda.

      Eliminar
  77. Hola comencé a utilizar phpword, estoy intentando modificar el margen a la Hora de insertar una imagen mas no lo consigo la puedo alinear derecha, izquierda al centro, mas no puedo modificar los márgenes use 'marginTop'=> -"",'marginLeft'=> -"", mas no lo consigo no sé si me pudieras orientar un poco.

    ResponderEliminar
    Respuestas
    1. En la documentación oficial viene:

      http://phpword.readthedocs.io/en/latest/elements.html#images

      Eliminar
    2. Hola gracias buenos dias, ya la había revisado la documentación mas sin embargo tengo problemas con ella no me realiza las modificaciones inserta la imagen pero la posición de los margenes según los margenes que pongo no me los toma en cuenta toma en cuenta los de la pagina de la computadora donde la configure, tal vez es algo pequeño que paso por alto

      Eliminar
    3. createSection();

      // Add header
      /*$header = $section->createHeader();
      $table = $header->addTable();
      $table->addRow();
      //$table->addCell(4500)->addText('This is the header.');
      $table->addCell(4500)->addImage('_earth.png', array('width'=>150, 'height'=>100, 'align'=>'right', 'marginTop'=> - 10 ,
      'marginLeft' => 20 ,));
      */


      $section->addImage(
      '_earth.png' ,
      array(
      'width' => 150 ,
      'altura' => 150 ,
      'marginTop' => - 1 ,
      'marginLeft' => - 20 ,
      'wrappingStyle' => ' detrás'
      )
      );
      // Add footer
      $footer = $section->createFooter();
      $table = $footer->addTable();
      $table->addRow();
      $table->addCell(4500)->addImage('footer.jpg', array('width'=>600, 'height'=>150));
      //$footer->addPreserveText('Page {PAGE} of {NUMPAGES}.', array('align'=>'center'));

      // Write some text
      $section->addTextBreak();
      //$section->addText('Some text...');

      $section->addText(htmlspecialchars(
      'Fecha: 24-04-2017'),array('name' => 'Arial', 'size' => '11', 'bold' => false,' align '=> 'center'));
      $section->addText(htmlspecialchars(' Formato de venta de servicio '),
      array('name' => 'Arial', 'size' => '15', 'bold' => true),array('align'=>'left'));

      $section->addText(htmlspecialchars(
      ' Datos del Contacto '
      ), array('name' => 'Arial', 'size' => '10', 'bold' => true));

      $section->addText(htmlspecialchars('
      Cliente: MARIO ESQUIVEL E-mail: mario226c@hotmail.com No.Telefono:544545665456
      '
      ),
      array('name' => 'Arial', 'size' => '10', 'bold' => false));


      $section->addText(htmlspecialchars(
      ' Datos de facturacion
      '
      ),array('name' => 'Arial', 'size' => '11', 'bold' => true));


      $section->addText(htmlspecialchars(
      'RFC: riosdiosd Razon Social: ROSALVA SA DE CV
      E-mail: ROSSS@GMAIL.COM Telefono: 893483489 Ext: 34

      Domicilio: flor de higo


      Colonia: Morelia CP: 84598
      Municipio: Morelia1 Estado: Michoacan
      '
      ),array('name' => 'Arial', 'size' => '10', 'bold' => false));









      // Save File
      $objWriter = PHPWord_IOFactory::createWriter($PHPWord, 'Word2007');
      $objWriter->save('HeaderFooter.docx');

      header("Content-Disposition: attachment; filename='HeaderFooter.docx'");
      echo file_get_contents('HeaderFooter.docx');
      ?>

      Eliminar