Siempre vamos a necesitar imprimir en la mayoría de aplicaciones que desarrollemos, independientemente del lenguaje en el que lo hagamos. En este caso veremos cómo imprimir con HTML y Javascript, conservando los estilos y obteniendo una impresión que es exactamente igual a lo que vemos en pantalla.
Precisamente esta mañana tuve que investigar un método fácil, rápido y viable para imprimir contenedores, y aquí traigo los resultados.
Nota: para investigar la mayoría de lo que expongo aquí tomé como referencia la maravillosa respuesta a esta pregunta de StackOverflow
Actualización: he quitado los plunkers y he puesto enlaces directos; ya que que plnkr.co ha estado fallando y los estilos no se estaban cargando; por eso ahora mejor alojo los ejemplos en vivo en mi servidor. Abajo de cada explicación está el link. Sólo te contaba; porque esto no afectará tu experiencia de usuario ni el código expuesto; todo funciona como un encanto.
Aquí pondré la función pero un poco modificada. Primero, eliminé el encabezado, ya que si queremos incluir un encabezado lo ponemos en el mismo div, y si no, no lo incluimos.
En segundo lugar hice que reciba un elemento, no el id de un elemento. Es decir, la función recibe un elemento del DOM (obtenido con document.querySelector o con document.getElementById) en lugar de una cadena.
Así que queda así:
function imprimirElemento(elemento){
var ventana = window.open('', 'PRINT', 'height=400,width=600');
ventana.document.write('<html><head><title>' + document.title + '</title>');
ventana.document.write('</head><body >');
ventana.document.write(elemento.innerHTML);
ventana.document.write('</body></html>');
ventana.document.close();
ventana.focus();
ventana.print();
ventana.close();
return true;
}
Para este ejemplo vamos a crear 2 divs con diferente contenido y sólo imprimiremos uno de ellos. En el script ya puse la función que definimos arriba. Pondré un botón y cuando hagan click en él se imprimirá el contenido de un div.
El código para escuchar al botón es el siguiente:
document.querySelector("#btnImprimir").addEventListener("click", function() {
var div = document.querySelector("#imprimible");
imprimirElemento(div);
});
Mira el ejemplo en acción aquí.
Ya imprimimos el hola mundo, podemos pasar a cosas más avanzadas
El documento, sin estilos, a mi parecer se ve bonito; pero siempre tendremos la necesidad de cambiar alguna u otra cosa. Así que voy a agregar unos estilos sólo para demostrar el concepto. Para ello, le pondré al párrafo un padding de 18 px y un color de fondo color rosa.
Al encabezado le pondré el color azul. El estilo queda así:
h1 {
color: blue;
}
p {
padding: 18px;
background-color: pink;
}
Ahora vemos los cambios, pero si intentamos imprimir no se ve ningún estilo. Esto es porque al imprimir se crea un documento nuevo que no lleva los estilos css. Pero para cargarlos, podemos añadir lo siguiente a nuestra función para imprimir:
Nota: esta vez necesitamos modificar la función para imprimir y poner una función en el evento onload
de la ventana, para que primero cargue los estilos y luego imprima. Esto no es necesario si tu documento no lleva estilos.
function imprimirElemento(elemento) {
var ventana = window.open('', 'PRINT', 'height=400,width=600');
ventana.document.write('<html><head><title>' + document.title + '</title>');
ventana.document.write('<link rel="stylesheet" href="style.css">'); //Aquí agregué la hoja de estilos
ventana.document.write('</head><body >');
ventana.document.write(elemento.innerHTML);
ventana.document.write('</body></html>');
ventana.document.close();
ventana.focus();
ventana.onload = function() {
ventana.print();
ventana.close();
};
return true;
}
Y ahora sí, si imprimimos veremos algo así:
Si deseas probarlo en vivo haz click aquí.
Ahora sí podemos añadir cualquier estilo, e incluso podemos agregar 2, 3 o infinitas hojas de estilo. Para ello fue que esperamos al window.onload
, para que termine de cargar los estilos y luego imprima.
Si queremos que nuestro documento, al ser visualizado se vea de una forma pero al ser impreso de otra, podemos manejar dos hojas de estilo. Una para imprimir y otra normal. Para ello voy a crear una hoja de estilos nueva, en donde ahora el encabezado será rojo y el fondo del párrafo verde:
h1 {
color: red;
}
p {
padding: 18px;
background-color: green;
}
También al imprimir, cambiaremos la función para que ahora cargue una diferente hoja de estilos.
function imprimirElemento(elemento) {
var ventana = window.open('', 'PRINT', 'height=400,width=600');
ventana.document.write('<html><head><title>' + document.title + '</title>');
ventana.document.write('<link rel="stylesheet" href="imprimir.css">'); //Cargamos otra hoja, no la normal
ventana.document.write('</head><body >');
ventana.document.write(elemento.innerHTML);
ventana.document.write('</body></html>');
ventana.document.close();
ventana.focus();
ventana.onload = function() {
ventana.print();
ventana.close();
};
return true;
}
Ahora veamos los resultados. Normalmente, el documento luce así:
Pero al imprimir, se ve así:
Para terminar este tutorial demostraré cómo podemos imprimir diferentes contenedores, incluso aunque no sean divs.
Para ello crearé un párrafo con el id parrafo
, y pondré igualmente un botón. Así que el código HTML queda así:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="style.css">
</head>
<body>
<p id="parrafo">
Hola, soy un párrafo. También puedo ser <strong>impreso</strong>
<br> Olvidé decir que también puedo contener imágenes :)
<br>
<img src="https://d1q6f0aelx0por.cloudfront.net/product-logos/81630ec2-d253-4eb2-b36c-eb54072cb8d6-golang.png">
</p>
<button id="btnImprimirParrafo">Imprimir párrafo</button>
<div id="imprimible">
Hola, yo soy otro div con el id imprimible
<br> Puedo llevar
<br>saltos de línea
<br> También
<ul>
<li>Elementos</li>
<li>de una</li>
<li>Lista</li>
</ul>
<h1>Encabezados</h1>
<h2>De todos</h2>
<h3>Los tamaños</h3>
<p>Y <strong>todo</strong> lo que pueda ser <i>creado</i> usando <code>html</code></p>
</div>
<button id="btnImprimirDiv">Imprimir div</button>
<script src="script.js"></script>
</body>
</html>
Y para escuchar a los botones:
document.querySelector("#btnImprimirDiv").addEventListener("click", function() {
var div = document.querySelector("#imprimible");
imprimirElemento(div);
});
document.querySelector("#btnImprimirParrafo").addEventListener("click", function() {
var parrafo = document.querySelector("#parrafo");
imprimirElemento(parrafo);
});
Podemos probar el código en el siguiente enlace: ejemplo 4 de imprimir con HTML, JS y CSS.
Y así es como podemos jugar con los estilos y los elementos. Por cierto, podemos cambiar el tamaño de la ventana (que por defecto es de 400 x 600)
Hoy te voy a presentar un creador de credenciales que acabo de programar y que…
Ya te enseñé cómo convertir una aplicación web de Vue 3 en una PWA. Al…
En este artículo voy a documentar la arquitectura que yo utilizo al trabajar con WebAssembly…
En un artículo anterior te enseñé a crear un PWA. Al final, cualquier aplicación que…
Al usar Comlink para trabajar con los workers usando JavaScript me han aparecido algunos errores…
En este artículo te voy a enseñar cómo usar un "top level await" esperando a…
Esta web usa cookies.
Ver comentarios
Desde el cole no veía codigos, me ayudo bastante para arreglar los HTML de javascript para imprimir, super agradecida.
Funciona bien pero no puedo sacar la fecha que sale arriba. Como puedo sacarla? En la ventana nueva que se abre no aparece pero si aparece en la vista previa de la impresión y en el archivo guardado
Excelente, hasta el momento para lo estático funciona de maravilla, pero no he podido lograr que funciones con inputs, select option y demás. Conoces una librería o método para lograrlo?, he investigado y no doy con un resultado
Viendo y probando tu ejercicio, si funciona pero al momento de pasarlo a mi visual tal y como está me arroja un error al probarlo.
Hola. Recuerde que no se trata de solo copiar y pegar código, sino de entenderlo y adaptarlo.
Saludos :)
no están funcionando los estilos css lo implemente como tu amigo pero si me los carga en la pagina pero al momento de abrir el print no jala los colores.
Hola! hace tiempo que estoy tratando de generar un pdf desde las hojas de google sheets y aun no lo he logrado, la necesidad seria simple pero a la vez compleja, necesito un script que genere un link de un pdf dependiendo de las celdas de una fila, es decir cada vez que ingresa una nueva fila con sus respectivas celdas con informacion automaticamente se genere un link para poder imprimir esos datos, no toda la hoja, solo la fila, y sus datos horizontales, espero haber sido claro, abrazo!
Hola, no entiendo bien tu problema y a la vez es muy largo. Simplemente divídelo y resuelve cosa por cosa, una por una, hasta que al final logres el resultado. No es que no quiera ayudar, simplemente no viene con el tema del post. Saludos
Por favor serias tan amable ( mas de loq ue ya fuiste) y poner solo un codigo?, porque no logro hacerlo funcionar, todo en html+los script
Hola. En los ejemplos en vivo puedes ver el código fuente (con Ctrl + U o Click derecho > Ver código fuente). Así, puedes ver cómo se incluye el script y todo lo demás. Saludos.
men no estas aplicando los estilos en la impresión
Hola, muchas gracias por comentar. Plunker (que es en donde alojaba los ejemplos en vivo) ha estado fallando últimamente y no cargaba los estilos CSS. He movido los ejemplos a mi servidor y ahora van como un encanto. De nuevo gracias :)