从单个DIV创建PDF

5

编辑:DOMPDF不是必需的。欢迎使用其他从DIV打印PDF的解决方案。

我有一个基于单页面DOM的Web应用程序,登录时加载一次。

然后,页面上的每个操作都会触发某些div加载不同的内容和与mysql交互的php页面,使用PDO和AJAX。

我的问题是:

每个php页面只会echo需要适合特定DIV的HTML。

用户要求之一是考虑到特定DIV(具有内容的主要DIV)仅考虑打印PDF的可能性。我选择了DOMPDF来完成这项工作,但它需要有效的HTML标记才能运行,而不仅仅是一个部分。

我的想法是:添加一个复选框以选择PDF格式,我使用相同的ajax调用,但将其重定向到一个新的php页面,该页面将echo完整的HTML标记。

关键是结果应在新页面中打开(或在iframe中?),以便DOM PDF可以正确解析。

如何达到这一点?

我的实际AJAX调用:

$('#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);      
    }

});

这是在同一个div中加载soff_pdf.php页面的方法,与正常的ajax调用相同。

如何表达“在全新窗口打开”?或者有没有更好的方法来实现我想要的效果? soff_pdf.php(相关部分):

<?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");

?>

你并没有真正执行 Ajax。 - Daniel A. White
可能是使用JavaScript在新标签页中打开URL的重复问题。 - Daniel A. White
不是这样的。如果你仔细阅读问题,我想要的是从单个 div 中输出 pdf 的最佳方法。 - Lelio Faieta
DOMPDF在服务器端工作,我不认为在新窗口/选项卡/弹出窗口/iframe或其他任何内容中打开并将DOMPDF的输出提供给它会有任何问题。只需在服务器端小心处理即可。也许您应该展示使用DOMPDF的代码。 - Eggplant
请展示调用DOMPDF的相关代码。如果您想使用已经输出的一些HTML,则只需要操作输出缓冲区即可。最好使用一个变量来缓存生成的HTML,然后将其echo或传递给模板以生成PDF。 - Eggplant
显示剩余6条评论
1个回答

1
假设您正在客户端打开弹出窗口、新标签页或其他任何喜欢的方式,并且您希望重复使用已经输出您的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
    ));
}

模板可以是简单的以下内容:
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>PDF Output</title>
        <style>
            /* your style here */
        </style>
    </head>
    <body>
        {contents}
    </body>
</html>
编辑: 好的,我现在看到了你的代码,那么你可以很容易地调整我的示例以适应你的情况。你可以将$create_pdf_flag作为$_GET$_POST参数传递,然后你可以使用测试。
<?php if ($create_pdf_flag) { ?>
   some html here
 <?php } ?>

几次缩小html。

这可能是一个有效的解决方案。你对客户端有什么建议?使用iframe还是新窗口或者其他任何我喜欢的方式,因为没有最好的解决方案 :) ? - Lelio Faieta
1
你已经回答了自己 :) 我个人更喜欢新标签页,因为这样可以让用户(或用户的浏览器)决定是打开还是保存 PDF 文件。 - Eggplant

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接