How to export a DIV HTML to PDF by rederizing CSS?

Asked

Viewed 29,411 times

10

Does anyone have a code that can export a DIV to PDF by rendering all the CSS of this DIV? Is it better to do this in the backend (Java) or in the frontend (Javascript)? If anyone can help, thank you!!

EDIT: Thanks for the reply Gabriel Rodrigues, but this scheme there did not function the way I needOlha como sai o PDF, ele não renderiza o CSS

And the original page with css was like this: Print Original Pagina

  • I think this question might help you: http://answall.com/questions/714/howto export-uma-p%C3%A1gina-html-php-to-pdf

  • Welcome to Stackoverflow, before you ask a question, make sure there is already an answer by searching the site, if not, ask a question with enough details about your problem.

  • @Geferson looks at the java tag, this link refers to the pdf librarys for php, sergioBertolazo, has a library called jsPDF but it does not accept css, you can take a look tbm at html2canvas and use both for a solution.

  • Geferson this PHP solution will not serve in my case vlw!

  • Gabriel Rodrigues, thanks for the answer, I’ve tried using the jsPDF plugin but it didn’t work out the way I needed it, it just plays table data not CSS :/

  • @Gabrielrodrigues I know the post was php, but that doesn’t mean that the solution can’t be there, because there are lib that has versions for both java, php and several other languages, so before you just look at the topics and say that it’s wrong, it’s easy to take a look, including the two you quoted, is in the question mentioned.

  • There is no way to do this via javascript, it has to be on the same server. There are many plugins that do this... But depending on the tags your html has, some plugins can accept and others can not... I’ve had a lot of headache with this

  • Thanks for the reply Sergio, I tried using itext on the server, but it does not render css, you know some other bilioteca ?

  • I got only today after but a year, since that day I’m trying.. only today I got!!!! has only a little bug but I solve xD

Show 4 more comments

2 answers

13


Update

Based on the following reply, adapted the script and created a extended function of JQuery to facilitate the creation of PDF’s based on HTML. The script provides creating pages multiplies if the image size exceeds the A4 sheet limit, and keeps the CSS page.

Also available in gist.

(function($){
    $.fn.createPdf = function(parametros) {
        
        var config = {              
            'fileName':'html-to-pdf'
        };
        
        if (parametros){
            $.extend(config, parametros);
        }                            

        var quotes = document.getElementById($(this).attr('id'));

        html2canvas(quotes, {
            onrendered: function(canvas) {
                var pdf = new jsPDF('p', 'pt', 'letter');

                for (var i = 0; i <= quotes.clientHeight/980; i++) {
                    var srcImg  = canvas;
                    var sX      = 0;
                    var sY      = 980*i;
                    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');
                    ctx.drawImage(srcImg,sX,sY,sWidth,sHeight,dX,dY,dWidth,dHeight);

                    var canvasDataURL = onePageCanvas.toDataURL("image/png", 1.0);
                    var width         = onePageCanvas.width;
                    var height        = onePageCanvas.clientHeight;

                    if (i > 0) {
                        pdf.addPage(612, 791);
                    }

                    pdf.setPage(i+1);
                    pdf.addImage(canvasDataURL, 'PNG', 20, 40, (width*.62), (height*.62));
                }

                pdf.save(config.fileName);
            }
        });
    };
})(jQuery);
 

function createPDF() {
    $('#renderPDF').createPdf({
        'fileName' : 'testePDF'
    });
}
<!-- import -->

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.4.1/jspdf.min.js"></script> 
<script src="https://cdn.jsdelivr.net/npm/[email protected]/canvas2image.min.js"></script>

<!-- import -->


<button type="button" class="btn btn-success" onclick="createPDF();">pdf</button>
 
<div id="renderPDF" class="container">
	<div class="jumbotron">
		<h1>Bootstrap Tutorial</h1>
		<p>Bootstrap is the most popular HTML, CSS, and JS framework for developing responsive, mobile-first projects on the web.</p>
	</div>
	<div id="customers">
		<table id="tab_customers" class="table table-striped">
			<thead>
				<tr class='btn-danger'>
					<th>#</th>
					<th>Population</th>
					<th>Date</th>
					<th>Age</th>
				</tr>
			</thead>
			<tbody>
				<tr>
					<td>1</td>
					<td>1,363,480,000</td>
					<td>March 24, 2014</td>
					<td>19.1</td>
				</tr>
				<tr>
					<td>2</td>
					<td>1,241,900,000</td>
					<td>March 24, 2014</td>
					<td>17.4</td>
				</tr>
				<tr>
					<td>3</td>
					<td>317,746,000</td>
					<td>March 24, 2014</td>
					<td>4.44</td>
				</tr>
				<tr>
					<td>4</td>
					<td>249,866,000</td>
					<td>July 1, 2013</td>
					<td>3.49</td>
				</tr>
				<tr>
					<td>5</td>
					<td>201,032,714</td>
					<td>July 1, 2013</td>
					<td>2.81</td>
				</tr>
				<tr>
					<td>6</td>
					<td>1,363,480,000</td>
					<td>March 24, 2014</td>
					<td>19.1</td>
				</tr>
				<tr>
					<td>7</td>
					<td>1,241,900,000</td>
					<td>March 24, 2014</td>
					<td>17.4</td>
				</tr>
				<tr>
					<td>8</td>
					<td>317,746,000</td>
					<td>March 24, 2014</td>
					<td>4.44</td>
				</tr>
				<tr>
					<td>9</td>
					<td>249,866,000</td>
					<td>July 1, 2013</td>
					<td>3.49</td>
				</tr>
				<tr>
					<td>10</td>
					<td>201,032,714</td>
					<td>July 1, 2013</td>
					<td>2.81</td>
				</tr>
				<tr>
					<td>11</td>
					<td>1,363,480,000</td>
					<td>March 24, 2014</td>
					<td>19.1</td>
				</tr>
				<tr>
					<td>12</td>
					<td>1,241,900,000</td>
					<td>March 24, 2014</td>
					<td>17.4</td>
				</tr>
				<tr>
					<td>13</td>
					<td>317,746,000</td>
					<td>March 24, 2014</td>
					<td>4.44</td>
				</tr>
				<tr>
					<td>14</td>
					<td>249,866,000</td>
					<td>July 1, 2013</td>
					<td>3.49</td>
				</tr>
				<tr>
					<td>15</td>
					<td>201,032,714</td>
					<td>July 1, 2013</td>
					<td>2.81</td>
				</tr>
				<tr>
					<td>16</td>
					<td>1,363,480,000</td>
					<td>March 24, 2014</td>
					<td>19.1</td>
				</tr>
				<tr>
					<td>17</td>
					<td>1,241,900,000</td>
					<td>March 24, 2014</td>
					<td>17.4</td>
				</tr>
				<tr>
					<td>18</td>
					<td>317,746,000</td>
					<td>March 24, 2014</td>
					<td>4.44</td>
				</tr>
				<tr>
					<td>19</td>
					<td>249,866,000</td>
					<td>July 1, 2013</td>
					<td>3.49</td>
				</tr>
				<tr>
					<td>20</td>
					<td>201,032,714</td>
					<td>July 1, 2013</td>
					<td>2.81</td>
				</tr>
				<tr>
					<td>21</td>
					<td>1,363,480,000</td>
					<td>March 24, 2014</td>
					<td>19.1</td>
				</tr>
				<tr>
					<td>22</td>
					<td>1,241,900,000</td>
					<td>March 24, 2014</td>
					<td>17.4</td>
				</tr>
				<tr>
					<td>23</td>
					<td>317,746,000</td>
					<td>March 24, 2014</td>
					<td>4.44</td>
				</tr>
				<tr>
					<td>24</td>
					<td>249,866,000</td>
					<td>July 1, 2013</td>
					<td>3.49</td>
				</tr>
				<tr>
					<td>25</td>
					<td>201,032,714</td>
					<td>July 1, 2013</td>
					<td>2.81</td>
				</tr>
				<tr>
					<td>26</td>
					<td>1,363,480,000</td>
					<td>March 24, 2014</td>
					<td>19.1</td>
				</tr>
				<tr>
					<td>27</td>
					<td>1,241,900,000</td>
					<td>March 24, 2014</td>
					<td>17.4</td>
				</tr>
				<tr>
					<td>28</td>
					<td>317,746,000</td>
					<td>March 24, 2014</td>
					<td>4.44</td>
				</tr>
				<tr>
					<td>29</td>
					<td>249,866,000</td>
					<td>July 1, 2013</td>
					<td>3.49</td>
				</tr>
				<tr>
					<td>30</td>
					<td>201,032,714</td>
					<td>July 1, 2013</td>
					<td>2.81</td>
				</tr>
				<tr>
					<td>31</td>
					<td>1,363,480,000</td>
					<td>March 24, 2014</td>
					<td>19.1</td>
				</tr>
				<tr>
					<td>32</td>
					<td>1,241,900,000</td>
					<td>March 24, 2014</td>
					<td>17.4</td>
				</tr>
				<tr>
					<td>33</td>
					<td>317,746,000</td>
					<td>March 24, 2014</td>
					<td>4.44</td>
				</tr>
				<tr>
					<td>34</td>
					<td>249,866,000</td>
					<td>July 1, 2013</td>
					<td>3.49</td>
				</tr>
				<tr>
					<td>35</td>
					<td>201,032,714</td>
					<td>July 1, 2013</td>
					<td>2.81</td>
				</tr>
				<tr>
					<td>36</td>
					<td>1,363,480,000</td>
					<td>March 24, 2014</td>
					<td>19.1</td>
				</tr>
				<tr>
					<td>37</td>
					<td>1,241,900,000</td>
					<td>March 24, 2014</td>
					<td>17.4</td>
				</tr>
				<tr>
					<td>38</td>
					<td>317,746,000</td>
					<td>March 24, 2014</td>
					<td>4.44</td>
				</tr>
				<tr>
					<td>39</td>
					<td>249,866,000</td>
					<td>July 1, 2013</td>
					<td>3.49</td>
				</tr>
				<tr>
					<td>40</td>
					<td>201,032,714</td>
					<td>July 1, 2013</td>
					<td>2.81</td>
				</tr>
				<tr>
					<td>41</td>
					<td>1,363,480,000</td>
					<td>March 24, 2014</td>
					<td>19.1</td>
				</tr>
				<tr>
					<td>42</td>
					<td>1,241,900,000</td>
					<td>March 24, 2014</td>
					<td>17.4</td>
				</tr>
				<tr>
					<td>43</td>
					<td>317,746,000</td>
					<td>March 24, 2014</td>
					<td>4.44</td>
				</tr>
				<tr>
					<td>44</td>
					<td>249,866,000</td>
					<td>July 1, 2013</td>
					<td>3.49</td>
				</tr>
				<tr>
					<td>45</td>
					<td>201,032,714</td>
					<td>July 1, 2013</td>
					<td>2.81</td>
				</tr>
				<tr>
					<td>46</td>
					<td>1,363,480,000</td>
					<td>March 24, 2014</td>
					<td>19.1</td>
				</tr>
				<tr>
					<td>47</td>
					<td>1,241,900,000</td>
					<td>March 24, 2014</td>
					<td>17.4</td>
				</tr>
				<tr>
					<td>48</td>
					<td>317,746,000</td>
					<td>March 24, 2014</td>
					<td>4.44</td>
				</tr>
				<tr>
					<td>49</td>
					<td>249,866,000</td>
					<td>July 1, 2013</td>
					<td>3.49</td>
				</tr>
				<tr>
					<td>50</td>
					<td>201,032,714</td>
					<td>July 1, 2013</td>
					<td>2.81</td>
				</tr>
				<tr>
					<td>51</td>
					<td>1,363,480,000</td>
					<td>March 24, 2014</td>
					<td>19.1</td>
				</tr>
				<tr>
					<td>52</td>
					<td>1,241,900,000</td>
					<td>March 24, 2014</td>
					<td>17.4</td>
				</tr>
				<tr>
					<td>53</td>
					<td>317,746,000</td>
					<td>March 24, 2014</td>
					<td>4.44</td>
				</tr>
				<tr>
					<td>54</td>
					<td>249,866,000</td>
					<td>July 1, 2013</td>
					<td>3.49</td>
				</tr>
				<tr>
					<td>55</td>
					<td>201,032,714</td>
					<td>July 1, 2013</td>
					<td>2.81</td>
				</tr>
				<tr>
					<td>56</td>
					<td>1,363,480,000</td>
					<td>March 24, 2014</td>
					<td>19.1</td>
				</tr>
				<tr>
					<td>57</td>
					<td>1,241,900,000</td>
					<td>March 24, 2014</td>
					<td>17.4</td>
				</tr>
				<tr>
					<td>58</td>
					<td>317,746,000</td>
					<td>March 24, 2014</td>
					<td>4.44</td>
				</tr>
				<tr>
					<td>59</td>
					<td>249,866,000</td>
					<td>July 1, 2013</td>
					<td>3.49</td>
				</tr>
				<tr>
					<td>60</td>
					<td>201,032,714</td>
					<td>July 1, 2013</td>
					<td>2.81</td>
				</tr>
			</tbody>
		</table>
	</div>
</div>

________________________________________________________

Using the functions jspdf and html2canvas You can create a PDF without losing the CSS properties. However, one should be aware of the flow of creating the pdf.

The idea is to create an html image using html2canvas and subsequently use the hash(image) created to create the pdf using jspdf.

As the default PDF format is A4 format, we have to redefine the width of the div to A4 format and after creating the pdf, return to CSS normal.

First import the js in that order and after jquery:

Define a id the div that will be rendered.

Example:

<div id="renderPDF" class="container" style="background-color: #003399;">
  <h2>Basic Panel</h2>
  <div class="panel panel-default">
    <div class="panel-body">A Basic Panel</div>
  </div>
</div>

Going to the Javascript...

 <script language="javascript"> 
        var cache_width = $('#renderPDF').width(); //Criado um cache do CSS
        var a4  =[ 595.28,  841.89]; // Widht e Height de uma folha a4

        function getPDF(){
        // Setar o width da div no formato a4
        $("#renderPDF").width((a4[0]*1.33333) -80).css('max-width','none');

        // Aqui ele cria a imagem e cria o pdf
        html2canvas($('#renderPDF'), {
          onrendered: function(canvas) {
            var img = canvas.toDataURL("image/png",1.0);  
            var doc = new jsPDF({unit:'px', format:'a4'});
            doc.addImage(img, 'JPEG', 20, 20);
            doc.save('NOME-DO-PDF.pdf');
            //Retorna ao CSS normal
            $('#renderPDF').width(cache_width);
          }
        });
        }
    </script>
  • 2

    Perfect @Matheus. To complete, if anyone needs to print direct: doc.autoPrint();. + 1

  • This jsPDF you shared is no longer up to date. For those who need it you can use this one here: https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.2.61/jspdf.min.js

3

You can make a good solution by joining jsPDF and html2canvas

Example:

$('#button').click(function() {
  var doc = new jsPDF('landscape', 'pt', 'a4');
  doc.addHTML($('#conteudo'), function() {
    doc.save("teste.pdf");
  });
});
body {
  text-align: center;
}
div {
  color: #605B5B;
  background-color: white;
  padding: 50px;
  margin: 10px;
}
button {
  background-color: #44c767;
  -moz-border-radius: 28px;
  -webkit-border-radius: 28px;
  border-radius: 28px;
  border: 1px solid #18ab29;
  display: inline-block;
  cursor: pointer;
  color: #ffffff;
  font-family: Arial;
  font-size: 17px;
  padding: 16px 31px;
  text-decoration: none;
  text-shadow: 0px 1px 0px #2f6627;
}
button:active {
  position: relative;
  top: 1px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<script src="https://cdn.rawgit.com/MrRio/jsPDF/master/dist/jspdf.min.js"></script>
<script src="https://rawgit.com/niklasvh/html2canvas/master/dist/html2canvas.js"></script>

<div id="conteudo">
  <h1>Silvio Santos Ipsum!</h1>
  <p>boca sujuam... sem vergonhuamm. Mah é a porta da esperançaam. O Raul Gil é gayam! ... Maa O Ah Ae! Ih Ih! O Raul Gil é gayamm! Mah é a porta da esperançaam.</p>
  <p>
    Patríciaaammmm... Luiz Ricardouaaammmmmm. Ha haeeee. Hi hi. É namoro ou amizadeemm? Ma vale dérreaisam? Eu só acreditoammmm.... Vendoammmm. Mah você não consegue né Moisés? Você não consegueam. Um, dois três, quatro, PIM, entendeuam? Ma vejam só, vejam
    só.
  </p>
</div>

<button id="button">Baixar</button>

See working on jsfiddle

  • Thanks for the reply little brother, only this scheme did not work the way I need, it did not render the css

  • Comes out a black background type DOS screen correct? If it is, I’m in the same problem...

Browser other questions tagged

You are not signed in. Login or sign up in order to post.