Imprimir el contenido de un DIV

337

¿Cuál es la mejor manera de imprimir el contenido de un DIV?

prueba de uso
fuente
Intente imprimir elemento aquí
Gabe
1
¿Qué quieres decir con letra impresa? ¿Como en una impresora física?
Yuriy Faktorovich
"Imprimir" como en una impresora? o al documento?
Ed Schembor
He encontrado el mejor complemento desarrollado hasta ahora por etimbo github.com/etimbo/jquery-print-preview-plugin
MaxI
3
Solo como referencia para cualquiera que intente buscar una solución a esta cuestión de imprimir un div. La siguiente respuesta me pareció muy útil: stackoverflow.com/a/7532581/405117
Vikram

Respuestas:

518

Ligeros cambios con respecto a la versión anterior: probado en CHROME

function PrintElem(elem)
{
    var mywindow = window.open('', 'PRINT', 'height=400,width=600');

    mywindow.document.write('<html><head><title>' + document.title  + '</title>');
    mywindow.document.write('</head><body >');
    mywindow.document.write('<h1>' + document.title  + '</h1>');
    mywindow.document.write(document.getElementById(elem).innerHTML);
    mywindow.document.write('</body></html>');

    mywindow.document.close(); // necessary for IE >= 10
    mywindow.focus(); // necessary for IE >= 10*/

    mywindow.print();
    mywindow.close();

    return true;
}
Bill Paetzke
fuente
8
Esta es una solución rápida. La solución ideal es usar un CSS separado para imprimir. Quizás pueda explicar los detalles (requisitos) de su problema.
Bill Paetzke
66
Puede hacer referencia a la hoja de estilo en la ventana emergente. Agregue otra línea de código entre las etiquetas <head>: mywindow.document.write ('<link rel = "stylesheet" href = "main.css" type = "text / css" />');
Bill Paetzke
55
@Rahil cámbielo a esto: mywindow.document.close (); mywindow.focus (); mywindow.print (); mywindow.close ();
ROFLwTIME
3
^ agregue newwindow.focus (); para habilitar el navegador cruzado de impresión.
JackMahoney
77
A veces sucede si no se carga la vista previa de impresión, tal vez cuando el contenido para imprimir es bastante grande (lo noté solo con Chrome mientras la misma página imprime perfectamente en Firefox, sin embargo, no excluyo que pueda suceder en Firefox u otros navegadores también). La mejor manera que encontré es ejecutar la impresión (y cerrar) solo después de cargar Windows. Entonces, después: mywindow.document.write(data);Agregue esto: mywindow.document.write('<script type="text/javascript">$(window).load(function() { window.print(); window.close(); });</script>');Y elimine: mywindow.print();ymywindow.close();
Fabius
164

Creo que hay una mejor solución. Haga que su div para imprimir cubra todo el documento, pero solo cuando se imprima:

@media print {
    .myDivToPrint {
        background-color: white;
        height: 100%;
        width: 100%;
        position: fixed;
        top: 0;
        left: 0;
        margin: 0;
        padding: 15px;
        font-size: 14px;
        line-height: 18px;
    }
}
ANTES DE CRISTO.
fuente
Perfecto, mucho más agradable que una ventana emergente.
GreenWebDev
55
Desafortunadamente, no funcionará en IE como se esperaba, vea esto: stackoverflow.com/questions/975129/…
jarek.jpa
16
El contenido que debería desbordarse en varias páginas parece truncarse en Chrome.
Ishmael Smyrnow
En IE necesita ocultar el resto del documento. La modificación anterior de la siguiente manera funcionará: @media print {body * {display: none; } .myDivToPrint {display: block; color de fondo: blanco; altura: 100%; ancho: 100%; posición: fija; arriba: 0; izquierda: 0; margen: 0; acolchado: 15px; tamaño de fuente: 14px; altura de línea: 18 px; }}
RonnBlack
2
Es posible que deba poner el índice z: 9999999; en caso de que tenga otros elementos posicionados más arriba.
Adam M.
43

Aunque @gabe ha dicho esto , si está utilizando jQuery, puede usar mi printElementcomplemento.

Hay una muestra aquí , y más información sobre el plugin aquí .

El uso es bastante sencillo, simplemente tome un elemento con un selector jQuery e imprímalo:

$("#myDiv").printElement();

¡Espero que ayude!

Erik
fuente
14
8 años después, esto producirá "a.browser está indefinido" porque la llamada .browser se ha eliminado en jquery 1.9
KingsInnerSoul
1
@KingsInnerSoul no sea tan grosero con los usuarios de jQuery, estos tiempos son lo suficientemente duros para ellos; p
Alexandre Daubricourt
22

Usando Jquery, simplemente use esta función:

<script>
function printContent(el){
var restorepage = $('body').html();
var printcontent = $('#' + el).clone();
$('body').empty().html(printcontent);
window.print();
$('body').html(restorepage);
}
</script>

Su botón de impresión se verá así:

<button id="print" onclick="printContent('id name of your div');" >Print</button>

Editar: si TIENE datos de formulario que necesita conservar, clonar no lo copiará, por lo que solo tendrá que tomar todos los datos del formulario y reemplazarlos después de la restauración de la siguiente manera:

<script>
function printContent(el){
var restorepage = $('body').html();
var printcontent = $('#' + el).clone();
var enteredtext = $('#text').val();
$('body').empty().html(printcontent);
window.print();
$('body').html(restorepage);
$('#text').html(enteredtext);
}
</script>
<textarea id="text"></textarea>
Gary Hayes
fuente
$ ('body'). html (restorepage); no funcionará porque en ese momento no hay ningún elemento del cuerpo disponible. por lo tanto, será mejor reemplazarlo con location.reload ();
Depurador
No. Si vuelve a cargar la página, eliminará cualquier información en los formularios o cualquier otra configuración que pueda necesitar. Funciona perfectamente bien. Si se toma el tiempo de mirar el código, verá que la página de restauración var NO tiene toda la información de la página disponible para hacer el reemplazo. Deje de intentar editar mi código y pruébelo usted mismo o aprenda qué hace cada una de las partes de la función.
Gary Hayes
Esto es mejor. Incluye el diseño de la página al imprimir, a diferencia de los mencionados anteriormente, donde todavía necesito poner enlaces CSS desde el encabezado, etc. ¡Gracias!
Jorz
la forma en que has pasado eles terrible, especialmente desde que utilizas jQ. Mucho mejor simplemente pasar selectory deshacerse del código rígido#
RozzA
Siempre usé este método hoy, noté que no funciona correctamente en un dispositivo Android (Google Chrome). El área imprimible de la página cambia cada vez y contiene algunas partes adicionales el. Creo que el comando de impresión se envía cuando se restaura el cuerpo.
Ali Sheikhpour
18

Desde aquí http://forums.asp.net/t/1261525.aspx

<html>

<head>
    <script language="javascript">
        function printdiv(printpage) {
            var headstr = "<html><head><title></title></head><body>";
            var footstr = "</body>";
            var newstr = document.all.item(printpage).innerHTML;
            var oldstr = document.body.innerHTML;
            document.body.innerHTML = headstr + newstr + footstr;
            window.print();
            document.body.innerHTML = oldstr;
            return false;
        }
    </script>
    <title>div print</title>
</head>

<body>
    //HTML Page //Other content you wouldn't like to print
    <input name="b_print" type="button" class="ipt" onClick="printdiv('div_print');" value=" Print ">

    <div id="div_print">

        <h1 style="Color:Red">The Div content which you want to print</h1>

    </div>
    //Other content you wouldn't like to print //Other content you wouldn't like to print
</body>

</html>
huston007
fuente
1
se necesita una modificación para dividir footerStr en 2 partes. porque brwoser usa "</body>" como el final principal de la página actual. var footstr1 = "</"; var footstr2 = "cuerpo>"; var footerstr = footstr1 + footstr12;
mirzaei
13

Solía Bill Paetzkeresponder para imprimir un div que contenía imágenes pero no funcionaba con Google Chrome

solo necesitaba agregar esta línea myWindow.onload=function(){para que funcione y aquí está el código completo

<html>
<head>
    <script type="text/javascript" src="http://jqueryjs.googlecode.com/files/jquery-1.3.1.min.js"> </script>
    <script type="text/javascript">
        function PrintElem(elem) {
            Popup($(elem).html());
        }

        function Popup(data) {
            var myWindow = window.open('', 'my div', 'height=400,width=600');
            myWindow.document.write('<html><head><title>my div</title>');
            /*optional stylesheet*/ //myWindow.document.write('<link rel="stylesheet" href="main.css" type="text/css" />');
            myWindow.document.write('</head><body >');
            myWindow.document.write(data);
            myWindow.document.write('</body></html>');
            myWindow.document.close(); // necessary for IE >= 10

            myWindow.onload=function(){ // necessary if the div contain images

                myWindow.focus(); // necessary for IE >= 10
                myWindow.print();
                myWindow.close();
            };
        }
    </script>
</head>
<body>
    <div id="myDiv">
        This will be printed.
        <img src="image.jpg"/>
    </div>
    <div>
        This will not be printed.
    </div>
    <div id="anotherDiv">
        Nor will this.
    </div>
    <input type="button" value="Print Div" onclick="PrintElem('#myDiv')" />
</body>
</html>

Además, si alguien solo necesita imprimir un div con ID, no necesita cargar jquery

aquí hay código javascript puro para hacer esto

<html>
<head>
    <script type="text/javascript">
        function PrintDiv(id) {
            var data=document.getElementById(id).innerHTML;
            var myWindow = window.open('', 'my div', 'height=400,width=600');
            myWindow.document.write('<html><head><title>my div</title>');
            /*optional stylesheet*/ //myWindow.document.write('<link rel="stylesheet" href="main.css" type="text/css" />');
            myWindow.document.write('</head><body >');
            myWindow.document.write(data);
            myWindow.document.write('</body></html>');
            myWindow.document.close(); // necessary for IE >= 10

            myWindow.onload=function(){ // necessary if the div contain images

                myWindow.focus(); // necessary for IE >= 10
                myWindow.print();
                myWindow.close();
            };
        }
    </script>
</head>
<body>
    <div id="myDiv">
        This will be printed.
        <img src="image.jpg"/>
    </div>
    <div>
        This will not be printed.
    </div>
    <div id="anotherDiv">
        Nor will this.
    </div>
    <input type="button" value="Print Div" onclick="PrintDiv('myDiv')" />
</body>
</html>

espero que esto pueda ayudar a alguien

Robert
fuente
¡Esto funcionó para mí! El camelcase me mordió, ya que la respuesta original usa "mywindow" frente a "myWindow". ¡Gracias!
código de operación del
12
function printdiv(printdivname) {
    var headstr = "<html><head><title>Booking Details</title></head><body>";
    var footstr = "</body>";
    var newstr = document.getElementById(printdivname).innerHTML;
    var oldstr = document.body.innerHTML;
    document.body.innerHTML = headstr+newstr+footstr;
    window.print();
    document.body.innerHTML = oldstr;
    return false;
}

Esto imprimirá el divárea que desea y volverá a establecer el contenido como estaba. printdivnamees el divpara ser impreso.

Techie
fuente
se necesita una modificación para dividir footerStr en 2 partes. porque brwoser usa "</body>" como el final principal de la página actual. var footstr1 = "</"; var footstr2 = "cuerpo>"; var footerstr = footstr1 + footstr12;
mirzaei
Eso es ingenioso! Pero sí, necesitas el hack de mirzaei, de lo contrario, se rompe la etiqueta del cuerpo y obtienes un formato roto. Con el truco, ¡esto funciona muy bien! Incluso puede agregar su propio envoltorio interno para facilitar estilos de impresión especiales. Esta debería ser la respuesta aceptada.
user2662680
9

Cree una hoja de estilo de impresión separada que oculte todos los demás elementos, excepto el contenido que desea imprimir. Marcarlo usando 'media="print"cuando lo cargue:

<link rel="stylesheet" type="text/css" media="print" href="print.css" />

Esto le permite tener una hoja de estilo completamente diferente cargada para impresiones.

Si desea forzar que aparezca el cuadro de diálogo de impresión del navegador para la página, puede hacerlo así al cargar usando JQuery:

$(function() { window.print(); });

o desencadenado por cualquier otro evento que desee, como que un usuario haga clic en un botón.

Carl Russmann
fuente
2
Sí, eso también funcionaría; Es difícil, bueno, imposible, saber exactamente cuál es el escenario.
Puntiagudo
Estoy de acuerdo en que un CSS separado es la solución ideal. Y copiar el contenido del div a una nueva ventana es una solución rápida.
Bill Paetzke
9

Creo que las soluciones propuestas hasta ahora tienen los siguientes inconvenientes:

  1. Las soluciones de consulta de medios CSS suponen que solo hay un div para imprimir.
  2. Las soluciones javascript solo funcionan en ciertos navegadores.
  3. Destruir el contenido de la ventana principal y recrear eso crea un desastre.

He mejorado las soluciones anteriores. Aquí hay algo que he probado que funciona muy bien con los siguientes beneficios.

  1. Funciona en todos los navegadores, incluidos IE, Chrome, Safari y firefox.
  2. No destruye ni recarga la ventana principal.
  3. Puede imprimir cualquier cantidad de DIV en una página.
  4. Utiliza plantillas html para evitar la concatenación de cadenas propensa a errores.

Puntos clave a tener en cuenta:

  1. Debe tener un onload = "window.print ()" en la ventana recién creada.
  2. No llame a targetwindow.close () o targetwindow.print () desde el padre.
  3. Asegúrese de hacer targetwindow.document.close () y target.focus ()
  4. Estoy usando jquery pero puedes hacer la misma técnica usando javascript simple.
  5. Puedes ver esto en acción aquí http://math.tools/table/multiplication . Puede imprimir cada tabla por separado, haciendo clic en el botón Imprimir en el encabezado del cuadro.

<script id="print-header" type="text/x-jquery-tmpl">
   <html>
   <header>
       <title>Printing Para {num}</title>
       <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
       <style>
          body {
            max-width: 300px;
          }
       </style>
   </header>
   <body onload="window.print()">
   <h2>Printing Para {num} </h2>
   <h4>http://math.tools</h4>
</script>
<script id="print-footer" type="text/x-jquery-tmpl">
    </body>
    </html>
</script>
<script>
$('.printthis').click(function() {
   num = $(this).attr("data-id");
   w = window.open();
   w.document.write(
                   $("#print-header").html().replace("{num}",num)  +
                   $("#para-" + num).html() +
                   $("#print-footer").html() 
                   );
   w.document.close();
   w.focus();
   //w.print(); Don't do this otherwise chrome won't work. Look at the onload on the body of the newly created window.
   ///w.close(); Don't do this otherwise chrome won't work
});
</script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<a class="btn printthis" data-id="1" href="#" title="Print Para 1"><i class="fa fa-print"></i> Print Para 1</a>
<a class="btn printthis" data-id="2" href="#" title="Print Para 2"><i class="fa fa-print"></i> Print Para 2</a>
  
<p class="para" id="para-1">
  Para 1 : Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
  

<p class="para" id="para-2">
  Para 2 : Lorem 2 ipsum 2 dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
  

dors
fuente
¡Esto fue excelente y funcionó entre navegadores mucho mejor que los resultados aceptados!
dama_do_bling
7

Creé un complemento para abordar este escenario. No estaba contento con los complementos, y me propuse hacer algo más extenso / configurable.

https://github.com/jasonday/printThis

Jason
fuente
1
Muchas gracias por tu arduo trabajo Jason ..... !! Realmente voy a usar en mis más proyectos. Qué alucinante plugin man ...... Sin palabras .....
6

La solución aceptada no estaba funcionando. Chrome estaba imprimiendo una página en blanco porque no estaba cargando la imagen a tiempo. Este enfoque funciona:

Editar: Parece que la solución aceptada se modificó después de mi publicación. ¿Por qué el voto negativo? Esta solución también funciona.

    function printDiv(divName) {

        var printContents = document.getElementById(divName).innerHTML;
        w = window.open();

        w.document.write(printContents);
        w.document.write('<scr' + 'ipt type="text/javascript">' + 'window.onload = function() { window.print(); window.close(); };' + '</sc' + 'ript>');

        w.document.close(); // necessary for IE >= 10
        w.focus(); // necessary for IE >= 10

        return true;
    }
vive el amor
fuente
4

Sé que esta es una vieja pregunta, pero resolví este problema con jQuery.

function printContents(id) {
    var contents = $("#"+id).html();

    if ($("#printDiv").length == 0) {
      var printDiv = null;
      printDiv = document.createElement('div');
      printDiv.setAttribute('id','printDiv');
      printDiv.setAttribute('class','printable');
      $(printDiv).appendTo('body');
    }

    $("#printDiv").html(contents);

    window.print();

    $("#printDiv").remove();
}

CSS

  @media print {
    .non-printable, .fancybox-outer { display: none; }
    .printable, #printDiv { 
        display: block; 
        font-size: 26pt;
    }
  }
Llamativo
fuente
3

Aunque la respuesta @BC fue la mejor para imprimir una sola página.

Pero puede ser útil imprimir varias páginas de tamaño A4 al mismo tiempo con Ctrl + P.

@media print{
html *{
    height:0px!important;
    width:0px !important;
    margin: 0px !important;
    padding: 0px !important;
    min-height: 0px !important;
    line-height: 0px !important;
    overflow: visible !important;
    visibility: hidden ;


}


/*assing myPagesClass to every div you want to print on single separate A4 page*/

 body .myPagesClass {
    z-index: 100 !important;
    visibility: visible !important;
    position: relative !important;
    display: block !important;
    background-color: lightgray !important;
    height: 297mm !important;
    width: 211mm !important;
    position: relative !important;

    padding: 0px;
    top: 0 !important;
    left: 0 !important;
    margin: 0 !important;
    orphans: 0!important;
    widows: 0!important;
    overflow: visible !important;
    page-break-after: always;

}
@page{
    size: A4;
    margin: 0mm ;
    orphans: 0!important;
    widows: 0!important;
}}
arslan
fuente
2
  • Abrir una nueva ventana
  • Abra el objeto de documento de la nueva ventana y escriba en él un documento simple que no contenga nada más que el div que tiene y el encabezado html necesario, etc.
  • Ponga un script en la nueva página para llamar a window.print ()
  • Activa el guión
Puntiagudo
fuente
2

Aquí está mi complemento de impresión jquery

(function ($) {

$.fn.printme = function () {
    return this.each(function () {
        var container = $(this);

        var hidden_IFrame = $('<iframe></iframe>').attr({
            width: '1px',
            height: '1px',
            display: 'none'
        }).appendTo(container);

        var myIframe = hidden_IFrame.get(0);

        var script_tag = myIframe.contentWindow.document.createElement("script");
        script_tag.type = "text/javascript";
        script = myIframe.contentWindow.document.createTextNode('function Print(){ window.print(); }');
        script_tag.appendChild(script);

        myIframe.contentWindow.document.body.innerHTML = container.html();
        myIframe.contentWindow.document.body.appendChild(script_tag);

        myIframe.contentWindow.Print();
        hidden_IFrame.remove();

    });
};
})(jQuery);
karaxuna
fuente
2

Si desea tener todos los estilos del documento original (incluidos los estilos en línea) puede utilizar este enfoque.

  1. Copia el documento completo
  2. Reemplace el cuerpo con el elemento que desea imprimir.

Implementación:

class PrintUtil {
  static printDiv(elementId) {
    let printElement = document.getElementById(elementId);
    var printWindow = window.open('', 'PRINT');
    printWindow.document.write(document.documentElement.innerHTML);
    setTimeout(() => { // Needed for large documents
      printWindow.document.body.style.margin = '0 0';
      printWindow.document.body.innerHTML = printElement.outerHTML;
      printWindow.document.close(); // necessary for IE >= 10
      printWindow.focus(); // necessary for IE >= 10*/
      printWindow.print();
      printWindow.close();
    }, 1000)
  }   
}
Stefan Norberg
fuente
2
No sé si esta es la mejor solución, pero funcionó perfectamente. ¡Gracias!
BRogers
2

Nota: Esto funciona solo con sitios habilitados para jQuery

Es muy simple con este truco genial. Me funcionó en el navegador Google Chrome . Firefox no le permitirá imprimir en PDF sin un complemento.

  1. Primero, abra el inspector usando (Ctrl + Shift + I) / (Cmd + Opción + I).
  2. Escriba este código en la consola:

var jqchild = document.createElement('script');
jqchild.src = "https://cdnjs.cloudflare.com/ajax/libs/jQuery.print/1.5.1/jQuery.print.min.js";
document.getElementsByTagName('body')[0].appendChild(jqchild);
$("#myDivWithStyles").print(); // Replace ID with yours
  1. Inicia el diálogo de impresión. Tome una impresión física o guárdela en PDF (en cromo). ¡Hecho!

La lógica es simple. Estamos creando una nueva etiqueta de script y adjuntándola frente a la etiqueta de cierre del cuerpo. Inyectamos una extensión de impresión jQuery en el HTML. Cambie myDivWithStyles con su propia ID de etiqueta Div. Ahora se encarga de preparar una ventana virtual imprimible.

Pruébalo en cualquier sitio. La única advertencia es que, a veces, el CSS escrito con engaño puede hacer que falten estilos. Pero obtenemos el contenido la mayoría de las veces.

Naren Yellavula
fuente
1

En Opera, prueba:

    print_win.document.write('</body></html>');
    print_win.document.close(); // This bit is important
    print_win.print();
    print_win.close();
tenebroso
fuente
1

Aquí hay una solución IFrame que funciona para IE y Chrome:

function printHTML(htmlString) {
    var newIframe = document.createElement('iframe');
    newIframe.width = '1px';
    newIframe.height = '1px';
    newIframe.src = 'about:blank';

    // for IE wait for the IFrame to load so we can access contentWindow.document.body
    newIframe.onload = function() {
        var script_tag = newIframe.contentWindow.document.createElement("script");
        script_tag.type = "text/javascript";
        var script = newIframe.contentWindow.document.createTextNode('function Print(){ window.focus(); window.print(); }');
        script_tag.appendChild(script);

        newIframe.contentWindow.document.body.innerHTML = htmlString;
        newIframe.contentWindow.document.body.appendChild(script_tag);

        // for chrome, a timeout for loading large amounts of content
        setTimeout(function() {
            newIframe.contentWindow.Print();
            newIframe.contentWindow.document.body.removeChild(script_tag);
            newIframe.parentElement.removeChild(newIframe);
        }, 200);
    };
    document.body.appendChild(newIframe);
}
kofifus
fuente
1

Creó algo genérico para usar en cualquier elemento HTML

HTMLElement.prototype.printMe = printMe;
function printMe(query){             
     var myframe = document.createElement('IFRAME');
     myframe.domain = document.domain;
     myframe.style.position = "absolute";
     myframe.style.top = "-10000px";
     document.body.appendChild(myframe);
     myframe.contentDocument.write(this.innerHTML) ;
     setTimeout(function(){
        myframe.focus();
        myframe.contentWindow.print();
        myframe.parentNode.removeChild(myframe) ;// remove frame
     },3000); // wait for images to load inside iframe
     window.focus();
}
//usage
document.getElementById('xyz').printMe();
document.getElementsByClassName('xyz')[0].printMe();

Espero que esto ayude.

Gaurav
fuente
1

Modifiqué la respuesta de @BillPaetski para usar querySelector, agregar CSS opcional, eliminar la etiqueta H1 forzada y hacer que el título se especifique o extraiga opcionalmente de la ventana. Tampoco se imprime automáticamente y expone los elementos internos para que puedan cambiarse en la función de envoltura o como desee.

Los únicos dos vars privados son tmpWindow y tmpDoc, aunque creo que el acceso de título, css y elem puede variar, se debe suponer que todos los argumentos de la función son privados.

Código:
function PrintElem(elem, title, css) {
    var tmpWindow = window.open('', 'PRINT', 'height=400,width=600');
    var tmpDoc = tmpWindow.document;

    title = title || document.title;
    css = css || "";

    this.setTitle = function(newTitle) {
        title = newTitle || document.title;
    };

    this.setCSS = function(newCSS) {
        css = newCSS || "";
    };

    this.basicHtml5 = function(innerHTML) {
        return '<!doctype html><html>'+(innerHTML || "")+'</html>';
    };

    this.htmlHead = function(innerHTML) {
        return '<head>'+(innerHTML || "")+'</head>';
    };

    this.htmlTitle = function(title) {
        return '<title>'+(title || "")+'</title>';
    };

    this.styleTag = function(innerHTML) {
        return '<style>'+(innerHTML || "")+'</style>';
    };

    this.htmlBody = function(innerHTML) {
        return '<body>'+(innerHTML || "")+'</body>';
    };

    this.build = function() {
        tmpDoc.write(
            this.basicHtml5(
                this.htmlHead(
                    this.htmlTitle(title) + this.styleTag(css)
                ) + this.htmlBody(
                    document.querySelector(elem).innerHTML
                )
            )
        );
        tmpDoc.close(); // necessary for IE >= 10
    };

    this.print = function() {
        tmpWindow.focus(); // necessary for IE >= 10*/
        tmpWindow.print();
        tmpWindow.close();
    };

    this.build();
    return this;
}
Uso:
DOMPrinter = PrintElem('#app-container');
DOMPrinter.print();
MrMesees
fuente
Además, no copia los valores de los <input>elementos. ¿Cómo puedo usar esto, incluido lo que el usuario ha escrito?
Malcolm Salvador
@ Malky.Kid, por favor piensa en lo que estás preguntando. Si desea imprimir un formulario, es necesario conectar la falta de definición de eventos de elementos de formulario, y establecer el valor del atributo, seleccionado, por defecto y innerText de <input>, <select>, <textarea>compontents para ser su valor de tiempo de ejecución. Hay alternativas, pero no es un problema con este script, sino un problema con el funcionamiento de los navegadores y la obtención de innerHTMLpropiedades de documentos con entradas, lienzo, etc.
MrMesees
Ya he llegado a una solución por vía .attr('value',). Incluso lo hice para textarea (agregando) y casillas de verificación ( .attr('checked',)). Lo siento si no estaba pensando lo suficiente sobre lo que estaba preguntando.
Malcolm Salvador
¿Te importaría compartir con la clase? tal vez una esencia o algo en los comentarios. Lo votaré.
MrMesees
0

El siguiente código copia todos los nodos relevantes a los que apunta el selector de consultas, copia sobre sus estilos como se ve en la pantalla, ya que faltarán muchos elementos principales utilizados para apuntar a los selectores CSS. Esto causa un poco de retraso si hay muchos nodos secundarios con muchos estilos.

Lo ideal sería tener una hoja de estilo de impresión lista, pero esto es para casos de uso donde no hay que insertar una hoja de estilo de impresión y desea imprimir como se ve en la pantalla.

Si copia los siguientes elementos en la consola del navegador en esta página, imprimirá todos los fragmentos de código en esta página.

+function() {
    /**
     * copied from  /programming/19784064/set-javascript-computed-style-from-one-element-to-another
     * @author Adi Darachi https://stackoverflow.com/users/2318881/adi-darachi
     */
    var copyComputedStyle = function(from,to){
        var computed_style_object = false;
        //trying to figure out which style object we need to use depense on the browser support
        //so we try until we have one
        computed_style_object = from.currentStyle || document.defaultView.getComputedStyle(from,null);

        //if the browser dose not support both methods we will return null
        if(!computed_style_object) return null;

            var stylePropertyValid = function(name,value){
                        //checking that the value is not a undefined
                return typeof value !== 'undefined' &&
                        //checking that the value is not a object
                        typeof value !== 'object' &&
                        //checking that the value is not a function
                        typeof value !== 'function' &&
                        //checking that we dosent have empty string
                        value.length > 0 &&
                        //checking that the property is not int index ( happens on some browser
                        value != parseInt(value)

            };

        //we iterating the computed style object and compy the style props and the values
        for(property in computed_style_object)
        {
            //checking if the property and value we get are valid sinse browser have different implementations
                if(stylePropertyValid(property,computed_style_object[property]))
                {
                    //applying the style property to the target element
                        to.style[property] = computed_style_object[property];

                }   
        }   

    };


    // Copy over all relevant styles to preserve styling, work the way down the children tree.
    var buildChild = function(masterList, childList) {
        for(c=0; c<masterList.length; c++) {
           var master = masterList[c];
           var child = childList[c];
           copyComputedStyle(master, child);
           if(master.children && master.children.length > 0) {
               buildChild(master.children, child.children);
           }
        }
    }

    /** select elements to print with query selector **/
    var printSelection = function(querySelector) {
        // Create an iframe to make sure everything is clean and ordered.
        var iframe = document.createElement('iframe');
        // Give it enough dimension so you can visually check when modifying.
        iframe.width = document.width;
        iframe.height = document.height;
        // Add it to the current document to be sure it has the internal objects set up.
        document.body.append(iframe);

        var nodes = document.querySelectorAll(querySelector);
        if(!nodes || nodes.length == 0) {
           console.error('Printing Faillure: Nothing to print. Please check your querySelector');
           return;
        }

        for(i=0; i < nodes.length; i++) {

            // Get the node you wish to print.
            var origNode = nodes[i];

            // Clone it and all it's children
            var node = origNode.cloneNode(true);

            // Copy the base style.
            copyComputedStyle(origNode, node);

            if(origNode.children && origNode.children.length > 0) {
                buildChild(origNode.children, node.children);
            }

            // Add the styled clone to the iframe. using contentWindow.document since it seems the be the most widely supported version.

            iframe.contentWindow.document.body.append(node);
        }
        // Print the window
        iframe.contentWindow.print();

        // Give the browser a second to gather the data then remove the iframe.
        window.setTimeout(function() {iframe.parentNode.removeChild(iframe)}, 1000);
    }
window.printSelection = printSelection;
}();
printSelection('.default.prettyprint.prettyprinted')
Tschallacka
fuente
0

Esta es una publicación muy antigua, pero aquí está una actualización de lo que hice con la respuesta correcta. Mi solución también usa jQuery.

El punto de esto es usar una vista de impresión adecuada, incluir todas las hojas de estilo para el formato adecuado y también ser compatible con la mayoría de los navegadores.

function PrintElem(elem, title, offset)
{
    // Title constructor
    title = title || $('title').text();
    // Offset for the print
    offset = offset || 0;

    // Loading start
    var dStart = Math.round(new Date().getTime()/1000),
        $html = $('html');
        i = 0;

    // Start building HTML
    var HTML = '<html';

    if(typeof ($html.attr('lang')) !== 'undefined') {
        HTML+=' lang=' + $html.attr('lang');
    }

    if(typeof ($html.attr('id')) !== 'undefined') {
        HTML+=' id=' + $html.attr('id');
    }

    if(typeof ($html.attr('xmlns')) !== 'undefined') {
        HTML+=' xmlns=' + $html.attr('xmlns');
    }

    // Close HTML and start build HEAD
    HTML+='><head>';

    // Get all meta tags
    $('head > meta').each(function(){
        var $this = $(this),
            $meta = '<meta';

        if(typeof ($this.attr('charset')) !== 'undefined') {
            $meta+=' charset=' + $this.attr('charset');
        }

        if(typeof ($this.attr('name')) !== 'undefined') {
            $meta+=' name=' + $this.attr('name');
        }

        if(typeof ($this.attr('http-equiv')) !== 'undefined') {
            $meta+=' http-equiv=' + $this.attr('http-equiv');
        }

        if(typeof ($this.attr('content')) !== 'undefined') {
            $meta+=' content=' + $this.attr('content');
        }

        $meta+=' />';

        HTML+= $meta;
        i++;

    }).promise().done(function(){

        // Insert title
        HTML+= '<title>' + title  + '</title>';

        // Let's pickup all CSS files for the formatting
        $('head > link[rel="stylesheet"]').each(function(){
            HTML+= '<link rel="stylesheet" href="' + $(this).attr('href') + '" />';
            i++;
        }).promise().done(function(){
            // Print setup
            HTML+= '<style>body{display:none;}@media print{body{display:block;}}</style>';

            // Finish HTML
            HTML+= '</head><body>';
            HTML+= '<h1 class="text-center mb-3">' + title  + '</h1>';
            HTML+= elem.html();
            HTML+= '</body></html>';

            // Open new window
            var printWindow = window.open('', 'PRINT', 'height=' + $(window).height() + ',width=' + $(window).width());
            // Append new window HTML
            printWindow.document.write(HTML);

            printWindow.document.close(); // necessary for IE >= 10
            printWindow.focus(); // necessary for IE >= 10*/
console.log(printWindow.document);
            /* Make sure that page is loaded correctly */
            $(printWindow).on('load', function(){                   
                setTimeout(function(){
                    // Open print
                    printWindow.print();

                    // Close on print
                    setTimeout(function(){
                        printWindow.close();
                        return true;
                    }, 3);

                }, (Math.round(new Date().getTime()/1000) - dStart)+i+offset);
            });
        });
    });
}

Más tarde, simplemente necesitas algo como esto:

$(document).on('click', '.some-print', function() {
    PrintElem($(this), 'My Print Title');
    return false;
});

Intentalo.

Ivijan Stefan Stipić
fuente
-1

Igual que la mejor respuesta, en caso de que necesite imprimir la imagen como lo hice yo:

En caso de que quiera imprimir la imagen:

function printElem(elem)
    {
        Popup(jQuery(elem).attr('src'));
    }

    function Popup(data) 
    {
        var mywindow = window.open('', 'my div', 'height=400,width=600');
        mywindow.document.write('<html><head><title>my div</title>');
        mywindow.document.write('</head><body >');
        mywindow.document.write('<img src="'+data+'" />');
        mywindow.document.write('</body></html>');

        mywindow.print();
        mywindow.close();

        return true;
    }
Goran Jakovljevic
fuente
Te estás perdiendo un loadevento en la ventana emergente. Sin ella, imprimirá una página en blanco ya que la imagen no está cargada. =>$(popup).load(function(){ popup.focus(); popup.print(); });
Tim Vermaelen
-4

La mejor manera de hacerlo sería enviar el contenido del div al servidor y abrir una nueva ventana donde el servidor podría poner esos contenidos en la nueva ventana.

Si esa no es una opción, puede intentar usar un lenguaje del lado del cliente como javascript para ocultar todo en la página excepto ese div y luego imprimir la página ...

muchacho
fuente
1
No es necesario devolverlo al servidor. Puede abrir una ventana del navegador y establecer el contenido e invocar el comando de impresión.
Jonathon Faust
Puede crear una nueva ventana desde el cliente.
Puntiagudo
1
Jonathon: Me gusta esa solución. ¿Tienes algún código de ejemplo?
usertest