Gerar pdf a partir do HTML em div usando Javascript

Tenho o seguinte 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>

tudo o que eu quero fazer é imprimir para pdf o que for encontrado no div com um id de "pdf". Isto deve ser feito usando JavaScript. O documento" pdf "deve então ser baixado automaticamente com um nome de arquivo de" foobar.pdf "

eu tenho usado jspdf para fazer isso, mas a única função que ele tem é "texto" que aceita apenas valores de cadeia. Eu quero enviar HTML para jspdf, Não texto.

Author: Lukasz Koziara, 2013-08-12

9 answers

JsPDF é capaz de usar plugins. para que possa imprimir HTML, você tem que incluir certos plugins e, portanto, tem que fazer o seguinte:

  1. vai para https://github.com/MrRio/jsPDF e descarrega a última versão.
  2. inclua os seguintes Scripts no seu projecto:
    • jspdf.js
    • jspdf.Forum.from_html.js
    • jspdf.Forum.split_text_to_size.js
    • jspdf.Forum.standard_fonts_metrics.js

Se você quiser ignorar certos elementos, você tem que marcá-los com um ID, que você pode então ignorar em um manipulador de elementos especiais do jsPDF. Portanto, o seu HTML deve ser parecido com este:

<!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>

Então você usa o seguinte código JavaScript para abrir o PDF criado em um 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 mim isto criou um PDF agradável e arrumado que só incluía a linha 'imprimir isto para pdf'.

Por favor, note que os manipuladores de elementos especiais só lidam com IDs na versão actual, o que também está indicado numa edição do GitHub. Diz:

Porque a correspondência é feita contra todos os elementos da árvore de nós, o meu desejo era torná-la o mais rápida possível. Nesse caso, significava "apenas elementos IDs são correspondidos" os elementos IDs ainda estão feitos no estilo jQuery "#id", mas isso não significa que todos os seletores jQuery são suportados.

Portanto, substituindo '#ignorePDF ' por selectores de classe como '.ignorePDF ' não trabalhou para mim. Em vez disso, você terá que adicionar o mesmo manipulador para cada elemento, que você quer ignorar como:

var elementHandler = {
  '#ignoreElement': function (element, renderer) {
    return true;
  },
  '#anotherIdToBeIgnored': function (element, renderer) {
    return true;
  }
};

Dos exemplos também está indicado que é possível seleccionar marcas como 'a' ou 'li'. Isso pode ser um pouco irrestrito para a maioria dos casos. embora:

Nós apoiamos manipuladores de elementos especiais. Regista-os com estilo jQuery. Selector de ID para o nome do ID ou do nó. ("#iAmID", "div", "span" etc.) Não existe suporte para qualquer outro tipo de selectores (classe, de composto) neste momento.

Uma coisa muito importante a adicionar é que você perde todas as informações de seu estilo (CSS). Felizmente jsPDF é capaz de formatar bem h1, h2, h3 etc. o que foi suficiente para os meus propósitos. Additionalyl só imprimirá texto dentro de nós de texto, o que significa que ele não vai imprimir os valores de áreas de texto e afins. Exemplo:

<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>
 156
Author: snrlx, 2015-01-06 09:00:12
Esta é a solução simples. Isto funciona comigo.Você pode usar o conceito de impressão javascript e simples salvar isso 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>
 27
Author: vaibhav kulkarni, 2015-11-24 10:04:38

Você pode usar o autoPrint () e configurar o resultado para 'dataurlnewwindow' como este:

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
}
 11
Author: Marco, 2015-08-24 14:47:03

Tal como mencionado, deve utilizar jsPDF e html2canvas. Também encontrei uma função dentro de edições do jsPDF que divide automaticamente o seu pdf em várias páginas ([[7]}Fontes)

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');
    }
  });
}
 7
Author: BaptWaels, 2017-02-17 14:07:00

Se quiser exportar uma tabela, poderá dar uma vista de olhos a Esta amostra de exportação fornecida pelo elemento da grelha de UI do Escudo.

É feito alargando a configuração desta forma:

...
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" }
            ]
        }
    }
}
...
 2
Author: Vladimir Georgiev, 2016-10-18 13:07:46

Se precisar de transferir pdf de uma página específica, basta adicionar um botão como este

<h4 onclick="window.print();"> Print </h4>

Usar a janela.imprimir () para imprimir a sua página Toda não apenas um div

 1
Author: Wael Mahmoud, 2018-03-09 17:48:32
Consegui que a jsPDF imprimisse tabelas criadas dinamicamente a partir de um 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 muito bem com cromo e Firefox... a formatação está toda explodida no IE.

Também incluí estes:

<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>
 0
Author: Wasskinny, 2015-03-12 11:52:07

Para capturar div como PDF você pode usar https://grabz.it solução. Tem uma API JavaScript que é fácil e flexível e lhe permitirá capturar o conteúdo de um único elemento HTML, como um div ou um span

Para implementá-lo, terá de obter primeiro uma chave de Aplicação e uma chave secreta e descarregar A SDK (livre).

E agora um exemplo. Vamos dizer que tens o 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 o que está sob os recursos id você terá de:

//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>

Por favor, note o target: #feature. #feature é o selector de CSS, como no exemplo anterior. Agora, quando a página é carregada uma imagem screenshot será agora criado no mesmo local que a tag script, que irá conter todo o conteúdo dos recursos div e nada mais.

As outras configurações e personalizações que poderá fazer ao mecanismo de captura de ecrã div; por favor verifique aqui

 0
Author: Stas, 2017-07-01 17:40:23
  • sem despenências, puro JS
Isto serviu-me durante anos.
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;
}
 0
Author: Lukas, 2018-05-06 13:45:58