Baixe um div em uma página HTML como pdf usando javascript

92

Eu tenho uma div de conteúdo com o id como "conteúdo". Na div de conteúdo, tenho alguns gráficos e algumas tabelas. Quero fazer o download desse div como um pdf quando o usuário clicar no botão de download. Existe uma maneira de fazer isso usando javascript ou jQuery?

Midhun Mathew
fonte
1
code.google.com/p/jspdf é a melhor biblioteca que conheço que pode fazer isso.
AlvinArulselvan
Como posso usar jsPDF para baixar um conteúdo em div específico? pelo que vejo nos exemplos em seu site, isso não pode ser feito.
Midhun Mathew

Respostas:

112

Você pode fazer isso usando jsPDF

HTML:

<div id="content">
     <h3>Hello, this is a H3 tag</h3>

    <p>A paragraph</p>
</div>
<div id="editor"></div>
<button id="cmd">generate PDF</button>

JavaScript:

var doc = new jsPDF();
var specialElementHandlers = {
    '#editor': function (element, renderer) {
        return true;
    }
};

$('#cmd').click(function () {
    doc.fromHTML($('#content').html(), 15, 15, {
        'width': 170,
            'elementHandlers': specialElementHandlers
    });
    doc.save('sample-file.pdf');
});
ilyes kooli
fonte
26
Eu tenho um problema aqui. O css que adicionei aqui não está sendo aplicado no arquivo pdf. Também tenho alguns gráficos ... esses não vêm no pdf. O que devo fazer para conseguir isso?
Midhun Mathew
15
jsPDF também não formata tabelas corretamente, ele apenas interpreta td / th como display: block;
Dave
2
Usando o código acima, podemos criar um pdf apenas uma vez. Mas, pela segunda vez, não está funcionando. Para fazer funcionar, verifique esta resposta por @ kristof-feys, Precisamos declarar a docvariável dentro da função de clique.
Mahendran Sakkarai
4
Isso é bom, só uma pena que o css não seja renderizado: /
Nicholas
1
Eu enfrentei um problema de codificação
ema
20

O conteúdo dentro de um <div class='html-content'>....</div>pode ser baixado como pdf com estilos usando jspdf e html2canvas .

Você precisa consultar as duas bibliotecas js,

<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.5.3/jspdf.min.js"></script>
<script type="text/javascript" src="https://html2canvas.hertzen.com/dist/html2canvas.js"></script>

Em seguida, chame a função abaixo,

//Create PDf from HTML...
function CreatePDFfromHTML() {
    var HTML_Width = $(".html-content").width();
    var HTML_Height = $(".html-content").height();
    var top_left_margin = 15;
    var PDF_Width = HTML_Width + (top_left_margin * 2);
    var PDF_Height = (PDF_Width * 1.5) + (top_left_margin * 2);
    var canvas_image_width = HTML_Width;
    var canvas_image_height = HTML_Height;

    var totalPDFPages = Math.ceil(HTML_Height / PDF_Height) - 1;

    html2canvas($(".html-content")[0]).then(function (canvas) {
        var imgData = canvas.toDataURL("image/jpeg", 1.0);
        var pdf = new jsPDF('p', 'pt', [PDF_Width, PDF_Height]);
        pdf.addImage(imgData, 'JPG', top_left_margin, top_left_margin, canvas_image_width, canvas_image_height);
        for (var i = 1; i <= totalPDFPages; i++) { 
            pdf.addPage(PDF_Width, PDF_Height);
            pdf.addImage(imgData, 'JPG', top_left_margin, -(PDF_Height*i)+(top_left_margin*4),canvas_image_width,canvas_image_height);
        }
        pdf.save("Your_PDF_Name.pdf");
        $(".html-content").hide();
    });
}

Ref: geração de pdf de canvas html e jspdf .

Pode ser que isso ajude alguém.

Vishnu S
fonte
4
Isso funcionou muito bem para mim, obrigado. Ele preserva todo o estilo, mas tem algumas limitações (cria o PDF como uma imagem para que não seja pesquisável; também parece um pouco desfocado).
jramm
como definir a quebra de página se metade do conteúdo não caber em uma página?
SHEKHAR SHETE
Funcionou muito bem para mim. O único problema é que alguns dos meus ícones SVG não foram renderizados!
Felipe N Moura
2

Sua solução requer algum método ajax para passar o html para um servidor back-end que tem um recurso de html para pdf e, em seguida, retornar a saída de pdf gerada de volta para o navegador.

Primeiro configurando o código do lado do cliente, vamos configurar o código jquery como

   var options = {
            "url": "/pdf/generate",
            "data": "data=" + $("#content").html(),
            "type": "post",
        }
   $.ajax(options)

Em seguida, intercepte os dados do script de geração html2pdf da seguinte forma

   $html = $_POST['data'];
   $pdf = html2pdf($html);

   header("Content-Type: application/pdf"); //check this is the proper header for pdf
   header("Content-Disposition: attachment; filename='some.pdf';");
   echo $pdf;

 

DevZer0
fonte
O que você quis dizer com "tem um recurso htmltopdf" ??
Midhun Mathew
posso referir o mesmo url ou devo alterá-lo?
Midhun Mathew
Você precisaria de um URL ligeiramente diferente para poder diferenciar entre os dois conteúdos
DevZer0
como deve ser esse url? Você pode dar um exemplo??
Midhun Mathew
2
Você ficará ferrado se o CSS estiver vinculado, porque seu programa de back-end não saberá onde encontrar os estilos a menos que possa pegar o arquivo CSS e aplicar os estilos de dentro do arquivo.
TheRealChx101
1

AFAIK não há função jquery nativa que faz isso. A melhor opção seria processar a conversão no servidor. Como você faz isso depende de qual idioma você está usando (.net, php etc.). Você pode passar o conteúdo do div para a função que trata da conversão, que retornaria um pdf ao usuário.

reggaemahn
fonte
-1

Sim, é possível capturar div como PDFs em JS. Você pode verificar a solução fornecida por https://grabz.it . Eles têm uma API JavaScript agradável e limpa que permite capturar o conteúdo de um único elemento HTML, como um div ou um intervalo.

Então, para usá-lo, você precisará de uma chave + app e do SDK gratuito . O uso dele é o seguinte:

Digamos que você tenha um 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 o ID de recursos, você precisará:

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

Você precisa substituir o http://www.example.com/my-page.htmlpelo seu URL de destino e #featurepor seu seletor de CSS.

Isso é tudo. Agora, quando a página é carregada, uma captura de tela da imagem será criada no mesmo local da tag do script, que conterá todo o conteúdo dos recursos div e nada mais.

Existem outras configurações e personalizações que você pode fazer no mecanismo div-screenshot, verifique-as aqui

Johnny
fonte
2
Eu acho que você só consegue 1.000 capturas grátis e 100 "scrapes" grátis com grabz.it. Portanto, não é uma solução permanente, a menos que você esteja disposto a pagar por isso.
BrettC 01 de