Exportar imagenes de html a word

publicado por: Anonymous

Partiendo de mi anterior pregunta, me gustaria saber como puedo exportar una imagen de html a Word, o por lo menos saber si es posible o no.

Tengo la siguiente tabla:

 <table id="test" class="table table-striped table-custom table-responsive">            
            <tbody id="tablabody">              
                <tr>
                    <td style="width:33.333333%">
                        <table class="table table-striped table-custom table-responsive">            
                            <tbody>             
                                <tr>
                                    <td><img src="/html/images/chico64.png" /></td>                 
                                </tr>
                                <tr>
                                    <td>Nombre: IKER</td>
                                    <td>Apellido: IKER</td>
                                </tr>
                            </tbody>
                        </table>                    
                    </td>
                    <td style="width:33.333333%">
                        <table class="table table-striped table-custom table-responsive">            
                            <tbody>             
                                <tr>
                                    <td><img src="/html/images/chico64.png" /></td>                 
                                </tr>
                                <tr>
                                    <td>Nombre: ANDONI</td>
                                    <td>Apellido: ANDONI</td>
                                </tr>
                            </tbody>
                        </table>                    
                    </td>
                    <td style="width:33.333333%">
                        <table class="table table-striped table-custom table-responsive">            
                            <tbody>             
                                <tr>
                                    <td><img src="/html/images/chica64.png" /></td>                 
                                </tr>
                                <tr>
                                    <td>Nombre: ERIKA</td>
                                    <td>Apellido: ERIKA</td>
                                </tr>
                            </tbody>
                        </table>                    
                    </td>                                       
                </tr>
            </tbody>
        </table>

La exporto con un botón que llama al siguiente método:

function creaWord(){    
var html = document.getElementById("test").outerHTML;
  var blob = new Blob(['ufeff', html], {
    type: 'application/msword'
  });
  var href = URL.createObjectURL(blob);
  var a = document.createElement('a');
  a.href = href;
  a.download = "documento.doc";
  document.body.appendChild(a);
  if (navigator.msSaveOrOpenBlob) {
    navigator.msSaveOrOpenBlob(blob, 'documento.doc');
  } else {
    a.click();
  }
  document.body.removeChild(a);
}

Esto me exporta correctamente a word el formato de la tabla, pero las imágenes me las exporta de esta manera. No se ni si se puede exportar imágenes a word de esta manera. Pero por lo menos aclarar si es posible o no, y si es posible como debería hacerlo.
Image

Edicion

Hay un jsfiddle que usa una librería externa y exporta imagenes. En un principio puede ser una solución valida pero me gustaría hacerlo sin usar librerías externas.

Por otra parte,he visto que en este jsfiddle convierte la imagen a base64 pero he probado ha hacer lo mismo (sin usar la librería) para ver si era cosa de la codificación pero sigue sin funcionar.

Edicion 2

Después de ver la baja calidad de mis resultados con javascript estoy probando a hacerlo con php.

Lo primero que he hecho es que el botón llame a la siguiente página php.

<?php
header("Content-type: application/vnd.ms-word");
header("Content-Disposition: attachment;Filename=documento.doc");

echo "<html>
<meta http-equiv="Content-Type" content="text/html; charset=Windows-1252">
<style> 
@page
{
    size:21cm 29.7cmt;  /* A4 */
    margin:1cm 1cm 1cm 1cm; /* Margins: 2.5 cm on each side */
    mso-page-orientation: portrait; 
}
@page Section1 { }
div.Section1 { page:Section1; }
p.MsoHeader, p.MsoFooter { border: 1px solid black; }
</style>
<body>
<div class=Section1>
<table id='test' style='  border: 1px solid black;'>            
    <tr>
        <td class='col-4' style='  border: 1px solid black;'>
            <div class='row' style='  border: 1px solid black;'>
                <div class='col-6' style='  border: 1px solid black;'>
                    <img id='img-0' src='/html/images/chico64.png' />
                </div>
                <div class='col-6' style='  border: 1px solid black;'>
                    <h1>1</h1>
                </div>
            </div>
            <div class='row' style='  border: 1px solid black;'>
                <div class='col-12' style='  border: 1px solid black;'>
                    Carrero Gomez, Iker
                </div>                      
            </div>
        </td>   
    </tr>
</table>
</div>
</body>
</html>";
?>

Hasta aquí todo funciona relativamente bien pero tengo dos problemas.

  1. El word se abre con la vista de diseño web, me gustaria saber como evitar esto y que se abra como un word normal.
  2. Las imágenes siguen sin exportarse.

La documentación para saber que estilos debo aplicar estoy usando esta página pero aún así creo que algunos como el salto de página no me terminan de funcionar.

solución

Una forma de hacerlo es convirtiendo las imágenes a base64. Si las imágenes están en tu servidor no vas a tener problemas con CORS (cross-origin resource sharing).

Le di un id a las imágenes

...<img id="img-0" src="/html/images/chico64.png" />...
...<img id="img-1" src="/html/images/chico64.png" />...
...<img id="img-2" src="/html/images/chica64.png" />...

Esta es la función que convierte el enlace con la imágen a base64:

function imgUrlABase64(url, callback) {
    var xhr = new XMLHttpRequest();
    xhr.onload = function() {
    var reader = new FileReader();
    reader.onloadend = function() {
      callback(reader.result);
    }
    reader.readAsDataURL(xhr.response);
    };
    xhr.open('GET', url);
    xhr.responseType = 'blob';
    xhr.send();
}

Modifiqué tu función creaWord para reemplazar el src de la imágen a base64. Simplemente reemplaza el enlace en el src por la codificación a base64. Mira a ver que el .replace encuentra y reemplaza el src correctamente. Asegurate que urlBase + document.getElementById("img-0") es el enlace con la imágen.

function creaWord(){        
    var html = document.getElementById("test").outerHTML;

    // -----------------------------------------------
    // CONVERTIR IMG SRC A BASE64
    var urlBase = window.location.href;
    var imgs = document.querySelectorAll('[id^=img-]');
    for (var i in imgs){
        imgUrlABase64(document.getElementById("img-0").src, 
            function(dataURL){
                html = html.replace(urlBase + document.getElementById("img-"+i), dataURL); 
            }
        );
    }
    // -----------------------------------------------


    var blob = new Blob(['ufeff', html], {
        type: 'application/msword'
    });
    var href = URL.createObjectURL(blob);
    var a = document.createElement('a');
    a.href = href;
    a.download = "documento.doc";
    document.body.appendChild(a);
    if (navigator.msSaveOrOpenBlob) {
        navigator.msSaveOrOpenBlob(blob, 'documento.doc');
    } else {
        a.click();
    }
    document.body.removeChild(a);
}

Si las imágenes no están en tu servidor mira a ver si alguna de estas otras soluciones te ayudan: https://stackoverflow.com/questions/6150289/how-to-convert-image-into-base64-string-using-javascript

EDICION 2

Esta es la respuesta usando PHP con la solución del OP en su Edición 2 y el estilo necesario para que el documento se abra en Word como texto y no como Web Layout.

<?php
    header("Content-type: application/vnd.ms-word");
    header("Content-Disposition: attachment;Filename=documento.doc");

    echo "<html 
            xmlns:o='urn:schemas-microsoft-com:office:office'
            xmlns:w='urn:schemas-microsoft-com:office:word' 
            xmlns='http://www.w3.org/TR/REC-html40'>
    <meta http-equiv="Content-Type" content="text/html; charset=Windows-1252">
    <head>
        <!--[if gte mso 9]>
            <xml>
            <w:WordDocument>
            <w:View>Print</w:View>
            <w:Zoom>90</w:Zoom> 
            <w:DoNotOptimizeForBrowser/>
            </w:WordDocument>
            </xml>
        <![endif]-->
    <style> 
    @page
    {
        size:21cm 29.7cmt;  /* A4 */
        margin:1cm 1cm 1cm 1cm; /* Margins: 2.5 cm on each side */
        mso-page-orientation: portrait; 
    }
    @page Section1 {
        size:21cm 29.7cm;  /* A4 */
        margin:1cm 1cm 1cm 1cm; /* Margins: 2.5 cm on each side */
        mso-header-margin: 2cm;
        mso-footer-margin: 2cm;
        mso-paper-source:0;
        mso-page-orientation: portrait; 
    }
    div.Section1 { page:Section1; }
    p.MsoHeader, p.MsoFooter { border: 1px solid black; }
    </style>
    </head>
    <body>
    <div class=Section1>
    <table id='test' style='  border: 1px solid black;'>            
        <tr>
            <td class='col-4' style='  border: 1px solid black;'>
                <div class='row' style='  border: 1px solid black;'>
                    <div class='col-6' style='  border: 1px solid black;'>
                        <img id='img-0' src='http://".$_SERVER['SERVER_NAME']."/html/images/chico64.png' />
                    </div>
                    <div class='col-6' style='  border: 1px solid black;'>
                        <h1>1</h1>
                    </div>
                </div>
                <div class='row' style='  border: 1px solid black;'>
                    <div class='col-12' style='  border: 1px solid black;'>
                        Carrero Gomez, Iker
                    </div>                      
                </div>
            </td>   
        </tr>
    </table>
    </div>
    </body>
    </html>";
?>
Respondido por: Anonymous

Leave a Reply

Your email address will not be published. Required fields are marked *