mostrar - Genera pdf desde HTML en div usando Javascript
obtener contenido de un div javascript (9)
Tengo el siguiente código html:
<!DOCTYPE html>
<html>
<body>
<p>don''t print this to pdf</p>
<div id="pdf">
<p><font size="3" color="red">print this to pdf</font></p>
</div>
</body>
</html>
Todo lo que quiero hacer es imprimir en pdf lo que se encuentre en el div con un id de "pdf". Esto debe hacerse usando JavaScript. El documento "pdf" se debe descargar automáticamente con un nombre de archivo de "foobar.pdf"
He estado usando jspdf para hacer esto, pero la única función que tiene es "texto", que acepta solo valores de cadena. Quiero enviar HTML a jspdf, no a texto.
Como se mencionó, debes usar https://github.com/MrRio/jsPDF y html2canvas . También encontré una función dentro de los problemas de jsPDF que divide automáticamente tu pdf en varias páginas ( sources )
function makePDF() {
var quotes = document.getElementById(''container-fluid'');
html2canvas(quotes, {
onrendered: function(canvas) {
//! MAKE YOUR PDF
var pdf = new jsPDF(''p'', ''pt'', ''letter'');
for (var i = 0; i <= quotes.clientHeight/980; i++) {
//! This is all just html2canvas stuff
var srcImg = canvas;
var sX = 0;
var sY = 980*i; // start 980 pixels down for every new page
var sWidth = 900;
var sHeight = 980;
var dX = 0;
var dY = 0;
var dWidth = 900;
var dHeight = 980;
window.onePageCanvas = document.createElement("canvas");
onePageCanvas.setAttribute(''width'', 900);
onePageCanvas.setAttribute(''height'', 980);
var ctx = onePageCanvas.getContext(''2d'');
// details on this usage of this function:
// https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Using_images#Slicing
ctx.drawImage(srcImg,sX,sY,sWidth,sHeight,dX,dY,dWidth,dHeight);
// document.body.appendChild(canvas);
var canvasDataURL = onePageCanvas.toDataURL("image/png", 1.0);
var width = onePageCanvas.width;
var height = onePageCanvas.clientHeight;
//! If we''re on anything other than the first page,
// add another page
if (i > 0) {
pdf.addPage(612, 791); //8.5" x 11" in pts (in*72)
}
//! now we declare that we''re working on that page
pdf.setPage(i+1);
//! now we add content to that page!
pdf.addImage(canvasDataURL, ''PNG'', 20, 40, (width*.62), (height*.62));
}
//! after the for loop is finished running, we save the pdf.
pdf.save(''test.pdf'');
}
});
}
Esta es la solución simple. Esto funciona para mí. Puede utilizar el concepto de impresión de JavaScript y guardarlo como PDF.
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script type="text/javascript">
$("#btnPrint").live("click", function () {
var divContents = $("#dvContainer").html();
var printWindow = window.open('''', '''', ''height=400,width=800'');
printWindow.document.write(''<html><head><title>DIV Contents</title>'');
printWindow.document.write(''</head><body >'');
printWindow.document.write(divContents);
printWindow.document.write(''</body></html>'');
printWindow.document.close();
printWindow.print();
});
</script>
</head>
<body>
<form id="form1">
<div id="dvContainer">
This content needs to be printed.
</div>
<input type="button" value="Print Div Contents" id="btnPrint" />
</form>
</body>
</html>
Para capturar div como PDF, puede usar la solución https://grabz.it . Tiene una API de JavaScript que es fácil y flexible y le permitirá capturar el contenido de un solo elemento HTML como div o span
Para implementarlo, primero deberá obtener una clave de la aplicación y un secreto, y download el SDK (gratuito).
Y ahora un ejemplo.
Digamos que tienes el HTML:
<div id="features">
<h4>Acme Camera</h4>
<label>Price</label>$399<br />
<label>Rating</label>4.5 out of 5
</div>
<p>Cras ut velit sed purus porttitor aliquam. Nulla tristique magna ac libero tempor, ac vestibulum felisvulput ate. Nam ut velit eget
risus porttitor tristique at ac diam. Sed nisi risus, rutrum a metus suscipit, euismod tristique nulla. Etiam venenatis rutrum risus at
blandit. In hac habitasse platea dictumst. Suspendisse potenti. Phasellus eget vehicula felis.</p>
Para capturar lo que está debajo de la identificación de funciones, necesitarás:
//add the sdk
<script type="text/javascript" src="grabzit.min.js"></script>
<script type="text/javascript">
//login with your key and secret.
GrabzIt("KEY", "SECRET").ConvertURL("http://www.example.com/my-page.html",
{"target": "#features", "format": "pdf"}).Create();
</script>
Tenga en cuenta el target: #feature
. #feature
es tu selector de CSS, como en el ejemplo anterior. Ahora, cuando se carga la página, se creará una captura de pantalla de la imagen en la misma ubicación que la etiqueta del script, que contendrá todos los contenidos de las características div y nada más.
Hay otra configuración y personalización que puede hacer con el mecanismo de captura de pantalla Div. Mire here
Pude obtener jsPDF para imprimir dinámicamente tablas creadas desde un div.
$(document).ready(function() {
$("#pdfDiv").click(function() {
var pdf = new jsPDF(''p'',''pt'',''letter'');
var specialElementHandlers = {
''#rentalListCan'': function (element, renderer) {
return true;
}
};
pdf.addHTML($(''#rentalListCan'').first(), function() {
pdf.save("caravan.pdf");
});
});
});
Funciona muy bien con Chrome y Firefox ... todo el formato está explotado en IE.
También incluí estos:
<script src="js/jspdf.js"></script>
<script src="js/jspdf.plugin.from_html.js"></script>
<script src="js/jspdf.plugin.addhtml.js"></script>
<script src="//mrrio.github.io/jsPDF/dist/jspdf.debug.js"></script>
<script src="http://html2canvas.hertzen.com/build/html2canvas.js"></script>
<script type="text/javascript" src="./libs/FileSaver.js/FileSaver.js"></script>
<script type="text/javascript" src="./libs/Blob.js/Blob.js"></script>
<script type="text/javascript" src="./libs/deflate.js"></script>
<script type="text/javascript" src="./libs/adler32cs.js/adler32cs.js"></script>
<script type="text/javascript" src="js/jspdf.plugin.addimage.js"></script>
<script type="text/javascript" src="js/jspdf.plugin.sillysvgrenderer.js"></script>
<script type="text/javascript" src="js/jspdf.plugin.split_text_to_size.js"></script>
<script type="text/javascript" src="js/jspdf.plugin.standard_fonts_metrics.js"></script>
Puede usar autoPrint () y establecer el resultado en ''dataurlnewwindow'' de esta manera:
function printPDF() {
var printDoc = new jsPDF();
printDoc.fromHTML($(''#pdf'').get(0), 10, 10, {''width'': 180});
printDoc.autoPrint();
printDoc.output("dataurlnewwindow"); // this opens a new popup, after this the PDF opens the print window view but there are browser inconsistencies with how this is handled
}
Si desea exportar una tabla, puede echar un vistazo a esta muestra de exportación proporcionada por el widget Shield UI Grid.
Se hace extendiendo la configuración de esta manera:
...
exportOptions: {
proxy: "/filesaver/save",
pdf: {
fileName: "shieldui-export",
author: "John Smith",
dataSource: {
data: gridData
},
readDataSource: true,
header: {
cells: [
{ field: "id", title: "ID", width: 50 },
{ field: "name", title: "Person Name", width: 100 },
{ field: "company", title: "Company Name", width: 100 },
{ field: "email", title: "Email Address" }
]
}
}
}
...
si necesita descargar el pdf de una página específica solo agregue un botón como este
<h4 onclick="window.print();"> Print </h4>
use window.print () para imprimir su página completa no solo un div
jsPDF puede usar complementos. Para poder imprimir HTML, debe incluir ciertos complementos y, por lo tanto, debe hacer lo siguiente:
- Vaya a https://github.com/MrRio/jsPDF y descargue la última versión.
- Incluya los siguientes Scripts en su proyecto:
- jspdf.js
- jspdf.plugin.from_html.js
- jspdf.plugin.split_text_to_size.js
- jspdf.plugin.standard_fonts_metrics.js
Si desea ignorar ciertos elementos, debe marcarlos con una ID, que luego puede ignorar en un controlador de elemento especial de jsPDF. Por lo tanto, su HTML debería verse así:
<!DOCTYPE html>
<html>
<body>
<p id="ignorePDF">don''t print this to pdf</p>
<div>
<p><font size="3" color="red">print this to pdf</font></p>
</div>
</body>
</html>
Luego, utiliza el siguiente código JavaScript para abrir el PDF creado en un PopUp:
var doc = new jsPDF();
var elementHandler = {
''#ignorePDF'': function (element, renderer) {
return true;
}
};
var source = window.document.getElementsByTagName("body")[0];
doc.fromHTML(
source,
15,
15,
{
''width'': 180,''elementHandlers'': elementHandler
});
doc.output("dataurlnewwindow");
Para mí, esto creó un PDF bonito y ordenado que solo incluía la línea ''imprimir esto en pdf''.
Tenga en cuenta que los manejadores de elementos especiales solo se ocupan de los ID en la versión actual, que también se menciona en un Issue de GitHub . Afirma:
Como la coincidencia se realiza con cada elemento del árbol de nodos, mi deseo era hacerlo lo más rápido posible. En ese caso, significaba que "solo los ID de los elementos se corresponden". Los ID de los elementos todavía se hacen en el estilo jQuery "#id", pero no significa que todos los selectores de jQuery son compatibles.
Por lo tanto, reemplazar ''#ignorePDF'' con selectores de clase como ''.ignorePDF'' no funcionó para mí. En su lugar, deberá agregar el mismo controlador para cada elemento, que desea ignorar como:
var elementHandler = {
''#ignoreElement'': function (element, renderer) {
return true;
},
''#anotherIdToBeIgnored'': function (element, renderer) {
return true;
}
};
De los examples también se afirma que es posible seleccionar etiquetas como ''a'' o ''li''. Sin embargo, eso podría ser un poco irrestrictivo para la mayoría de los usos:
Admitimos controladores de elementos especiales. Regístrelos con el selector ID de estilo jQuery para ID o nombre de nodo. ("#iAmID", "div", "span", etc.) No hay soporte para ningún otro tipo de selectores (clase, compuesto) en este momento.
Una cosa muy importante para agregar es que pierdes toda tu información de estilo (CSS). Afortunadamente jsPDF es capaz de formatear muy bien h1, h2, h3, etc., lo cual fue suficiente para mis propósitos. Additionalyl solo imprimirá texto dentro de los nodos de texto, lo que significa que no imprimirá los valores de textareas y similares. Ejemplo:
<body>
<ul>
<!-- This is printed as the element contains a textnode -->
<li>Print me!</li>
</ul>
<div>
<!-- This is not printed because jsPDF doesn''t deal with the value attribute -->
<input type="textarea" value="Please print me, too!">
</div>
</body>
- Sin dependencias, JS puro
Esto me sirvió por años ahora:
export default function printDiv({divId, title}) {
let mywindow = window.open('''', ''PRINT'', ''height=650,width=900,top=100,left=150'');
mywindow.document.write(`<html><head><title>${title}</title>`);
mywindow.document.write(''</head><body >'');
mywindow.document.write(document.getElementById(divId).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;
}