jspadf and canvas, does not screenshot the full modal

Asked

Viewed 116 times

2

I have the following code on the page where I check the data with the modal

(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(teste) {
    $('#employee_detail').createPdf({
        'fileName' : 'testePDF'
    });
}




$(document).on('click', '.view_data', function(){  
           var employee_id = $(this).attr("Id");  
           if(employee_id != '')  
           {  
                $.ajax({  
                     url:"./verutente1",  
                     method:"POST",  
                     data:{employee_id:employee_id},  
                     success:function(data){  
					 
                          $('#employee_detail').html(data);  
                          $('#dataModal').modal('show');  
                     }  
                });  
           }            
      });
<html>
<head>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/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>
</head>

<div id="dataModal" class="modal fade"> 
<div class="modal-dialog">  
<div class="modal-content">
<div class="container"></div>
<div class="modal-header">  
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span></button>
</div>
<button type="button" class="btn btn-success" onclick="createPDF();">pdf</button>
<div class="modal-body" id="employee_detail"> 
</div>
</div>
</div>  
</div>  

Then on the page verutente1 I have it as follows:

<?php
date_default_timezone_set('Europe/Lisbon');
if(isset($_POST["employee_id"]))  
 { 

$output = '';  

$query = "SELECT A.Id, codigo, A.nome, data, admissao, B.Discricao As Dependencia, quarto, civil, profissao, D.Discricao AS Estado, localidade, problemas, representante, C.Discricao AS Parentesco, 
telefone, localidade1, diabetica, alimentacao, apoio, restricoes, fraldas, familia, tipofraldas, Levante, Deitar, posicionamento, oculos, dentaria, queda, tecnicas, qual, grau, outras, E.nome AS enfermeiro
FROM raddb.Utente AS A LEFT OUTER JOIN raddb.Dependencia AS B ON B.Id = A.dependencia LEFT OUTER JOIN raddb.Parentesco AS C ON C.Id = A.parentesco 
LEFT OUTER JOIN raddb.EstadoUtilizador AS D ON D.Id = A.ativo LEFT OUTER JOIN raddb.usuarios AS E ON E.id = A.enfermeiro WHERE A.Id = '".$_POST["employee_id"]."'"; 

      $result = mysqli_query($conn, $query);  

      $output;

      while($row = mysqli_fetch_array($result))  
      {  

           $output .= '


                        <div class="modal-header">  
                        <h4 class="modal-title">Plano Individual de Cuidados</h4>
                        </div>
                        <div class="modal-body">  
                        <div class="table-responsive"> 
                        <form id="insert_form">
                        <div class="form-group input-group">
                         <span class="input-group-addon">
                         <span class="fa fa-file-code"> Código</span>
                         </span>
                         <input type="text" id="codigo1" name="codigo" value="'.$row["codigo"].'" class="form-control" readonly="true"/>
                         </div>
                        <div class="form-group input-group">
                         <span class="input-group-addon">
                         <span class="fa fa-user"> Nome</span>
                         </span>
                         <input type="text" id="nome1" name="nome" value="'.$row["nome"].'" class="form-control" readonly="true"/>
                         </div>
             </form>  
                </div>
                </div>  
           ';  
      }

      $output;
      echo $output;  
 }  

When I generate the pdf, it generates three pages, but the second and third are blank, as shown in pdf generated

But if in the <head> remove this bookstore:

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">

already generates the second page as shown in pdf generated, but remains unformatted.

The problem is that you are not taking the full modal screenshot, you only take what appears on the screen, what is off the screen does not show in the generated pdf, but creates in the pdf the number of sheets correctly. If you try to generate the pdf without being in modal, it works correctly. Libraries in get_header:

<head>
<meta charset="<?php bloginfo( 'charset' ); ?>">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="<?php echo of_get_option( 'nav_bg_color' ); ?>">
<link rel="profile" href="http://gmpg.org/xfn/11">
<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.3.3/jspdf.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script> 
<script src="https://unpkg.com/jspdf@latest/dist/jspdf.min.js"></script>
<script src="https://html2canvas.hertzen.com/dist/html2canvas.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/canvas2image.min.js"></script>

<?php wp_head(); ?>

</head>

On the new page1:

<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/canvas2image.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.4.1/jspdf.min.js"></script> 
<?php
/*
Template Name: novoutente1
 */
session_start();
get_header1();

?>
  • @Rdyego This question is related to the question link, will be able to see this after you have identified the problem?

1 answer

1


This is because the component considers the height of the body to generate the PDF. When opening the modal, the height of the page body is limited to what is seen on the screen.

What you need to do is set the height of the body at the same height of the div.modal-dialog modal, which is the div where the modal content is. By making the body the same height as that div, the component will capture all its content.

For this use the event shown.bs.modal to change the height of the body at the same height as the modal div, and the event hide.bs.modal to return the height from body to normal:

$('#dataModal').on('shown.bs.modal', function(){
   $("body").css("height", $('.modal-dialog', this).outerHeight()+"px");
}).on('hide.bs.modal', function(){
   $("body").css("height","auto");
});

Your code should look like this:

$('#dataModal').on('shown.bs.modal', function(){
   $("body").css("height", $('.modal-dialog', this).outerHeight()+"px");
}).on('hide.bs.modal', function(){
   $("body").css("height","auto");
});

(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(teste) {
    $('#employee_detail').createPdf({
        'fileName' : 'testePDF'
    });
}

$(document).on('click', '.view_data', function(){  
     var employee_id = $(this).attr("Id");  
     if(employee_id != '')  
     {  
          $.ajax({  
               url:"./verutente1",  
               method:"POST",  
               data:{employee_id:employee_id},  
               success:function(data){  
                    $('#employee_detail').html(data);  
                    $('#dataModal').modal('show');  
               }  
          });  
     }            
});
  • Friend still with the same problem, either only generates in the pdf the first sheet and the other two blank or returns the error I already mentioned above in the question

  • yes it works, but I think the problem is also in libraries. I need jquery to generate the pdf, but if you put jquery on the page where I will run the function I get the message that createPdf is not function. But if you remove get_header from the theme, I can already put jquery and it already works. I know that’s the problem, but I can’t explain it better, I don’t know why it happened

  • has to see the order that you are loading the libraries. jQuery must come before all.

  • and this is how I have it. I will publish the libraries and the order

  • From what I saw, the order is right, including on the test page I copied all your code.

  • if you remove this line from the header page, <?php wp_head(); ? >, it works, but if you remove the page you will be completely disfigured...

  • Libraries are different. You cannot load two jQuery at the same time.

  • but I’ve also tried it with jquery equal... It doesn’t work. I also ran a test here without calling get_header and it works well.... The problem is right there

  • has already been able to analyze the page code?

Show 5 more comments

Browser other questions tagged

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