13

I am trying to create an PDF file from a PHP page with jsPDF but it is not working and I dont know whats wrong.

Can someone help me?

First I have a Iframe. The page I want to convert is displayed in the Iframe:

Iframe:

<?php
    <iframe id="frame" name="frame" width="100%" height="1160px" frameborder="0" src="./page.php?id=' . $_GET['id'] . '"></iframe>
    <button id="cmd">Button</button>
?>

When I hit Button the following script should convert the page to PDF

Script

<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.3.2/jspdf.min.js"></script>
<script type="text/javascript">
    var doc = new jsPDF();

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

    $('#cmd').click(function () {
        doc.fromHTML($('frame').get(0), 15, 15, {
            'width': 170, 
            'elementHandlers': specialElementHandlers
        });

    doc.save('sample-file.pdf');
    });
</script>

But when I hit Button. Nothing is happening. Does someone know whats wrong?

John
  • 904
  • 8
  • 22
  • 56

3 Answers3

6

You must be get html of iframe, so use contents() function and then get documentElement of iframe:

<iframe id="frame" name="frame" width="100%" height="1160px" frameborder="0" src="http://localhost/"></iframe>
<button id="cmd">Button</button>
<script src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.3.2/jspdf.min.js"></script>
<script type="text/javascript">
    var doc = new jsPDF();

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

    $('#cmd').click(function () {
        doc.fromHTML($('#frame').contents().find('html').html(), 15, 15, {
            'width': 170, 
            'elementHandlers': specialElementHandlers
        });

    doc.save('sample-file.pdf');
    });
</script>

Note: If your iframe source page or part of it protected with x-frame-options header, you cannot access to html of it.

Bhumi Shah
  • 9,323
  • 7
  • 63
  • 104
Mohammad Hamedani
  • 3,304
  • 3
  • 10
  • 22
  • It isn't doing anything – John Jun 06 '17 at 01:33
  • It is creating an empty pdf file when I write: `doc.fromHTML($('iframe')`. The ID and NAMe of the iframe is `frame`. When I change `doc.fromHTML($('iframe')` to `doc.fromHTML($('frame')` it is not creating anymore – John Jun 06 '17 at 01:37
  • Try `doc.fromHTML($('#iframe').contents()[0].documentElement` – Mohammad Hamedani Jun 06 '17 at 02:25
  • It's still not creating a file. Maybe it is necessary for the answer. This is how the content of the iframe looks like: https://jsfiddle.net/ss6780qn/ – John Jun 06 '17 at 02:36
  • I saw your edit. It is creating a pdf file, but the PDF file is empty – John Jun 06 '17 at 03:47
  • I updated my answer and it runs successfully on localhost. But with https://jsfiddle.net/ss6780qn/ it has error, because that page protected from accessing cross-origin. Are you try it locally? – Mohammad Hamedani Jun 06 '17 at 03:48
  • Wait. It has a content now. When I click for the first time the script creates an empty PDF file. When I click again I get a PDF file with data. – John Jun 06 '17 at 03:55
  • Also the PDF file looks not not the same. The style looks different than the content of the Iframe – John Jun 06 '17 at 03:57
  • jsPDF doesn't support css. see https://stackoverflow.com/questions/20460035/jspdf-cant-get-any-styling-to-work – Mohammad Hamedani Jun 06 '17 at 04:00
  • So I need to change the HTML page then? – John Jun 06 '17 at 04:13
  • Do you have a solution for the new problem? That the script is first is creating an empty PDF file and the second time an filled PDF file? – John Jun 06 '17 at 04:14
  • Iframe needs to load completely, is it loaded? – Mohammad Hamedani Jun 06 '17 at 04:16
  • Yes, it is loaded – John Jun 06 '17 at 04:16
  • jsPDF has some function for set styles like [`setFontSize()`](http://rawgit.com/MrRio/jsPDF/master/docs/global.html#setFontSize), but it's limited! – Mohammad Hamedani Jun 06 '17 at 04:18
1
<button onclick="cmd()">Button</button>

Change this to

<button id="cmd">Button</button>

You are calling the click event in JS on the id. Or change the onclick event to a function with the name cmd.

rbaskam
  • 749
  • 7
  • 22
  • Still nothing is happening – John Jun 02 '17 at 11:53
  • By nothing is happening can you see the button? I see you've put HTML inside PHP tags. You should put the GET in PHP. If you can see the button then put some logging inside the click event and see if its triggering. – rbaskam Jun 02 '17 at 11:58
  • I forgot to delete the `()`. Now it is creating a PDF page. But the PDF is empty – John Jun 02 '17 at 11:58
  • Not sure but maybe change $('frame') to $('#frame') – rbaskam Jun 02 '17 at 12:01
  • No, its still empty – John Jun 02 '17 at 12:09
  • Sorry but I have never used the package you are using but I am just testing now. Here is a similar question that relates to your new problem that may help in the meantime. https://stackoverflow.com/questions/22184659/cannot-make-pdf-from-html-div-by-jspdf – rbaskam Jun 02 '17 at 12:11
  • Here someone is trying to do what you are doing. I haven't tested it but it may help. https://stackoverflow.com/questions/16415506/download-pdf-file-from-an-iframe-content-with-jspdf – rbaskam Jun 02 '17 at 13:02
1

Apparently, jsPDF has limitations and/or bugs. It has problems with complex tables (especially with colspans). It throws javascript errors which stops the renderer which is why you're getting blank pdfs.

https://github.com/MrRio/jsPDF/issues/516

https://github.com/MrRio/jsPDF/issues/595

A fork has been posted here: https://github.com/jutunen/jsPDF-table_2 but I'm not sure if it addresses other limitations of jsPDF.

aljo f
  • 2,430
  • 20
  • 22