5

EDIT: DOMPDF is not mandatory. Any other solution to print a PDF from a DIV is welcome.

I have a web application that is based on a single page DOM that is loaded once on login.

Then, each action on the page will trigger some div to load different contents and php pages to interact with mysql using PDO and AJAX.

My issue is the following:

Each php page will echo just the HTML that needs to fit in that particular DIV.

One of the user requirements is the possibilty to print a PDF taking into account only a specific DIV (the main one with the contents). I have selected DOMPDF to do the job but it requires a valid html markup to run and not only a section.

My idea would be: adding a checkbox to select PDF format I use the same ajax call but redirect it to a new php page that will echo the full html markup.

The point is that the result should open in a new page (or in a iframe??) to be parsed correctly by DOM PDF.

How to get this point?

My actual AJAX call:

$('#livesearch').on("click",'a', function(event){
    event.preventDefault();
    var tip = $(this).attr("href");
    var descr = $(this).text();
    $('#anag_search').val(descr);
    $('#livesearch').hide();
    if ($('#pdfprint').prop('checked')) {
        $('#upper').load('sofferenze/soff_pdf.php?soff='+tip);      
    }else{
        $('#upper').load('sofferenze/soff.php?soff='+tip);      
    }

});

This is loading the soff_pdf.php page in the same div as the normal ajax call.

How to say "open in a brand new window"?? Or is there a better way to get what I am looking for? The soff_pdf.php (relevant part):

<?php
require '../../session_handler.inc.php';
require_once '../../global_functions.php';
require_once '../../dompdf/dompdf_config.inc.php';
session_start();
$actusr = $_SESSION['id'];
$id_soff = $_GET['soff'];
$soff_name = soff2name($id_soff,$pdo);
//query to fetch data are here
?>
<?php ob_start(); ?>
<!DOCTYPE html>

<html>
    <head>
<meta content="charset=utf-8" />
<title>DEVELOPMENT SYSTEM</title>
<link rel="stylesheet" type="text/css" href="../../css/style.css" media="screen" />
<link rel="stylesheet" type="text/css" href="../../css/style_print.css" media="print"/>
<script type="text/javascript" src="../../js/jquery-1.9.1.min.js"></script>
</head>
<body>
<br><br>
<div id="accordion">
    <h3>Crediti inclusi nella sofferenza</h3>
    <div>
    <table class="report">
        <caption class="report">Crediti Chirografari</caption>
        <thead>
        <tr>
            <!--<th class="report">Codice</th>-->
            <th class="report">Sofferenza</th>
            <th class="report">GBV</th>
            <th class="report">Data GBV</th>
            <th class="report">Titolare</th>
            <th class="report">Serie</th>
            <th class="report">Data Acq.</th>
            <th class="report">Cedente</th>
            <th class="report">Tipo</th>
            <th class="report">Originator</th>
                <th class="report">Stato</th>
        </tr>
        </thead>
        <tbody>
        <?php if(count($crediti_chiro) >0){ foreach($crediti_chiro as $credito_chiro){ ?>
        <tr>
            <!--<td class="report"><?php //echo $credito_chiro['id_cre']; ?></td>-->
            <td class="report"><?php echo soff2name($credito_chiro['cod_soff'],$pdo); ?></td>
            <td class="report"><?php echo num2cur($credito_chiro['gbv_tot']); ?></td>
            <td class="report"><?php echo mysql2table($credito_chiro['gbv_data']); ?></td>
            <td class="report"><?php echo get_name('veicoli',$credito_chiro['titolare'],'nome',$pdo); ?></td>
            <td class="report"><?php echo get_name('serie',$credito_chiro['cod_serie'],'serie',$pdo); ?></td>
            <td class="report"><?php echo mysql2table($credito_chiro['data_acq']); ?></td>
            <td class="report"><?php echo prot2name($credito_chiro['cedente'],$pdo); ?></td>
            <td class="report"><?php echo get_name('diz_cred',$credito_chiro['tipo'],'descrizione',$pdo); ?></td>
            <td class="report"><?php echo prot2name($credito_chiro['originator'],$pdo); ?></td>
            <td class="report"><?php echo $credito_chiro['stato']; ?></td>
        </tr>
        <?php }}else{ ?>
            <td class="report" colspan="10">Nessun credito chirografario caricato</td>
        <?php }?>
        </tbody>
    </table>
<br><br>

</div>
 <!-- more html here -->
</body></html>
<?php

$html = ob_get_clean();
$dompdf = new DOMPDF();
$dompdf->load_html($html);
$dompdf->render();
$dompdf->stream("sample.pdf");

?>
Lelio Faieta
  • 6,457
  • 7
  • 40
  • 74
  • you aren't really doing ajax. – Daniel A. White May 05 '15 at 13:04
  • possible duplicate of [Open a URL in a new tab using JavaScript](http://stackoverflow.com/questions/4907843/open-a-url-in-a-new-tab-using-javascript) – Daniel A. White May 05 '15 at 13:04
  • Ok, but this is not the point. I am dinamically loading a piece of HTML instead of a full DOM into another page – Lelio Faieta May 05 '15 at 13:05
  • It is not. If you read the question what I am looking for is the best way to output a pdf out of a single div. – Lelio Faieta May 05 '15 at 13:06
  • DOMPDF works server side, I don't see any problem opening a new window/tab/popup/iframe/whatever feeding to it the output of DOMPDF. Just take care of it server side. Maybe you should show the code that uses DOMPDF. – Eggplant May 05 '15 at 13:07
  • @Eggplant the point is that DOMPDF (i know it a bit) requires a valid html markup to run and not just a subset of a full page. – Lelio Faieta May 05 '15 at 13:08
  • This is a long shot, but can't you just parse the html and add the missing enclosing tags to make it valid? – Ernesto May 05 '15 at 13:11
  • I know DOMPDF, that's why I've told you should deal with the problem server side. I guess you have some script that generates that html subset you are talking about, then why can't you use the same output from another function/class/script, enclosing it into a template (made specifically for pdf output) and feed it to DOMPDF? – Eggplant May 05 '15 at 13:12
  • I could. But maybe there is a better way to parse the entire page (the DOM initially loaded) and print only that div (that is what actually my css for printing does) in DOMPDF – Lelio Faieta May 05 '15 at 13:13
  • @Eggplant this is what I am looking to do. The soff_pdf.php echoes a full html page with a markup and the call to the DOMPDF functions to create the PDF. But the thing is not working fine. I have no problem with dompdf on a full page. – Lelio Faieta May 05 '15 at 13:16
  • Please show the relevant code calling DOMPDF then. If you want to use some html you have already *echoed* then all you need is manipulate the [output buffer](http://php.net/manual/en/ref.outcontrol.php). It would be better to use a variable to buffer the generated html and either echo or pass it to a template to generate a pdf. – Eggplant May 05 '15 at 13:20

1 Answers1

1

Assuming you are opening a popup or new tab or whatever you prefer client side and you want to re-use the same script that already echoes your html:

if ($create_pdf_flag) ob_start();

echo 'some html...';
echo 'some more html...';
echo 'some other html...';
echo 'yet some more html...';

if ($create_pdf_flag) {
    $contents = ob_get_contents();
    ob_end_clean();

    $html = file_get_contents('/path/to/your/template.html');
    $html = str_replace('{contents}', $contents, $html);

    $DOMPDF = new DOMPDF();
    $DOMPDF->load_html($html);
    $DOMPDF->render();
    $DOMPDF->stream('Filename.pdf', array(
        'compress'      => 1,
        'Attachment'    => 0
    ));
}

The template could be something as simple as:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>PDF Output</title>
        <style>
            /* your style here */
        </style>
    </head>
    <body>
        {contents}
    </body>
</html>

EDIT : Ok I've seen your code now, then you could easily adapt my example to your case. You can pass the $create_pdf_flag as a $_GET or $_POST parameter and you could use the test

<?php if ($create_pdf_flag) { ?>
   some html here
 <?php } ?>

a few times to shrink the html.

Eggplant
  • 1,903
  • 1
  • 14
  • 24
  • this could be a valid solution. What do you advice on client side? Iframe or new window or whatever I like cause there is not a best solution :) ? – Lelio Faieta May 05 '15 at 13:38
  • 1
    You answered yourself :) Personally I prefer a new tab, because it leaves to the user (or user's browser) the decision to open or save the pdf. – Eggplant May 05 '15 at 13:39