【问题标题】:PHP Form result to Dompdf PDFPHP 表单结果到 Dompdf PDF
【发布时间】:2020-05-20 11:26:37
【问题描述】:

我正在尝试通过 DOMPDF 将 PHP 生成的表单的结果导出为 PDF。但它会生成一个空白页。可能是生成的 HTML 有一些问题。

PHP 脚本如下。我只是在这里粘贴 HTML 输出,因为 PHP 文件很长并且有很多功能。所以我猜这是 HTML 格式的问题:

<?php 
require_once 'dompdf/autoload.inc.php';
use Dompdf\Dompdf;
?>
<!DOCTYPE html>
<head>
<title>Country Language</title>
</head>
<body>

<?php ob_start(); ?>
<form>
<table border="1"><tr><td><b>Countries Selected</b></td><td><b>Details</b></td><td><b>Amount</b></td></tr>  
    <tr>
        <td rowspan='8'><h2>Australia</h2></td>
    </tr>
    <tr>
        <td>&nbsp;Z</td>
        <td>3</td>
    </tr>
        <tr>
        <td>&nbsp;Entity</td>
        <td>&nbsp;</td>
    </tr>
    <tr>
        <td>&nbsp;N</td>
        <td>&nbsp;0</td>
    </tr>
    <tr>
        <td>English to English</td>
        <td>&nbsp;</td>
    </tr>
    <tr>
        <td>&nbsp;X</td>
        <td>&nbsp;1</td>
    </tr>
    <tr>
        <td>&nbsp;Y</td>
        <td>&nbsp;2</td>
    </tr>
    <tr>
        <td><strong>TOTAL PATENT FEE</strong></td>
        <td><b>&nbsp;USD&nbsp;1400.45</b></td>
    </tr>
    <tr>
        <td rowspan='8'><h2>India</h2></td>
    </tr>
    <tr>
        <td>&nbsp;Z</td>
        <td>3</td>
    </tr>
        <tr>
        <td>&nbsp;Entity</td>
        <td>&nbsp;Micro</td>
    </tr>
    <tr>
        <td>&nbsp;N</td>
        <td>&nbsp;1</td>
    </tr>
    <tr>
        <td>Arabic to English</td>
        <td>&nbsp;</td>
    </tr>
    <tr>
        <td>&nbsp;X</td>
        <td>&nbsp;1</td>
    </tr>
    <tr>
        <td>&nbsp;Y</td>
        <td>&nbsp;2</td>
    </tr>
    <tr>
        <td><strong>TOTAL PATENT FEE</strong></td>
        <td><b>&nbsp;USD&nbsp;315.45</b></td>
    </tr>
</table>



<?php
if ( isset( $_GET['pdf'] ) ) {
  $html = ob_get_contents();
  $html = ob_get_clean();
  $dompdf = new DOMPDF();
  $dompdf->load_html($html);
  $dompdf->setPaper('A4', 'portrait');
  $dompdf->render();
  $dompdf->stream("the_inquiry.pdf");
}
?>
<div class="shouldPrintToPDF">
    <a  href="/general/cean/cost-calc5.php?&amp;pdf=1" class="pdflink">Open as PDF</a>
  </div>
</form>
</body>
</html>

PHP 脚本如下:

<?php
require_once 'dompdf/autoload.inc.php';
use Dompdf\Dompdf;


    if (isset($_GET['pdf'])) {
    ob_start(); 
}
else {
?>

<!DOCTYPE html>
<head>
<title>Country Language</title>
</head>
<body>
<form>



<?php

if(isset($_POST['submit'])) {
$language_selected = $_POST['language'];
$claims_selected = $_POST['claims'];
$pages_selected = $_POST['pages'];
$totalwords_selected = $_POST['totalwords'];
$claims_selected = $_POST['claims'];
$entity_selected1 = $_POST['entity_selected'];


//echo '<div class="container">';
echo '<form>';

        echo '<table border="1">';
        echo '<tr><td><b>Countries Selected</b></td><td><b>Fee Details</b></td><td><b>Amount</b></td></tr>';

            foreach ($_POST['check_list'] as $key => $country_checked) {

                if(!empty($_POST['entity_selected'][$key])) {
                $entity_selected = $_POST['entity_selected'][$key];
                } else {
                $entity_selected = '';
                }

            $sql_db = mysqli_query($conn,"SELECT id, country, language, entity FROM country_languages where country = '$country_checked' ");
            //$row_db = mysqli_fetch_assoc($sql_db);
                while($row_db = mysqli_fetch_array($sql_db)) {
                    $id = $row_db["id"];
                    $country = $row_db["country"];
                    $language = $row_db["language"];
                    $entity = $row_db["entity"];
                        if ($language_selected == $language) {
                         $Z = '0';
                        } else {
                         $Z = $totalwords_selected;
                        }
                             if ($entity_selected =='') {
                                $N = '0';
                             } else if ($entity_selected == 'Micro') {
                                $N = '1';
                             } else if (($entity_selected == 'Small') AND ($country_checked == 'India')) {
                                $N = '2.2';
                             }  else if (($entity_selected == 'Small') AND ($country_checked !== 'India')) {
                                $N = '2';
                             } else if (($entity_selected == 'Large') AND ($country_checked == 'India')) {
                                $N = '4.4';
                             } else if (($entity_selected == 'Large') AND ($country_checked == 'Philippines')) {
                                $N = '5.5';
                             } else if (($entity_selected == 'Large') AND ($country_checked !== 'Philippines') AND ($country_checked !== 'India')) {
                                $N = '4';
                             } else {
                                $N = '0';
                             }
                            $X = $claims_selected;
                            $Y = $pages_selected;
                        if ($country_checked == 'USA') {
                        $result = (430 + 25 * ($X - 20) + 200 * (($Y - 100) / 50 + (1 - ($Y - 100) / 50))) * $N + 0.15 * $Z + 750;  
                        } else {
                        $result = 'Not able to fetch data.';
                        }

?>
    <tr>
        <td rowspan='8'><h2><?php echo $country_checked; ?></h2></td>
    </tr>
    <tr>
        <td>&nbsp;Z</td>
        <td><?php echo $Z; ?></td>
    </tr>
        <tr>
        <td>&nbsp;Entity</td>
        <td>&nbsp;<?php echo $entity_selected; ?></td>
    </tr>
    <tr>
        <td>&nbsp;N</td>
        <td>&nbsp;<?php echo $N; ?></td>
    </tr>
    <tr>
        <td><?php echo $language_selected; ?> to <?php echo $language; ?></td>
        <td>&nbsp;</td>
    </tr>
    <tr>
        <td>&nbsp;X</td>
        <td>&nbsp;<?php echo $X; ?></td>
    </tr>
    <tr>
        <td>&nbsp;Y</td>
        <td>&nbsp;<?php echo $Y; ?></td>
    </tr>
    <tr>
        <td><strong>TOTAL PATENT FEE</strong></td>
        <td><b>&nbsp;USD&nbsp;<?php echo number_format((float)$result, 2, '.', ''); ?></b></td>
    </tr>
<?php
}   // END WHILE LOOP   
    } //END FOR LOOP
echo '</table>';
}

?>

<?php
if (isset($_GET['pdf'])) {
  $html = ob_get_clean();
  $dompdf = new DOMPDF();
  $dompdf->load_html($html);
  $dompdf->setPaper('A4', 'portrait');
  $dompdf->render();
  $dompdf->stream("the_inquiry.pdf");
} 

else {
?>
<div class="shouldPrintToPDF">
<a href="<?php echo $_SERVER['PHP_SELF'] , '?' , http_build_query( $_GET ); ?>&amp;pdf=1" class="pdflink">Open or save as PDF</a>

</div>
</form>
</body>
</html>

<?php }  }?>

【问题讨论】:

  • 虽然它与您的代码易受 SQL 注入攻击的问题没有密切联系!请查看 mysqli 准备好的语句并使用它们。您的代码也容易受到跨站脚本攻击,因为您不会转义从 URL 获得的数据(例如:$_SERVER['PHP_SELF'])。
  • 只有在发出 POST 请求并且数据可用于生成表时才会生成表。当您单击 PDF 链接时,会发出 GET 请求。您可以通过使用 GET 而不是 POST 发送和接收数据来解决它。 (例如:$_POST['language'] => $_GET['language'])。另一种解决方案是将 PDF 链接替换为发送必要数据的表单(它可以是带有隐藏输入字段的不可见表单)。
  • 好的。你能给我一个用不可见表单替换 PDF 链接的样本吗
  • 我用一个小例子更新了我的答案。希望对你有帮助!
  • 生成字段或表单结果的循环太多了。无论如何感谢您的帮助。非常感谢您的时间。

标签: php dompdf


【解决方案1】:

问题在于,即使 pdf 查询字符串存在于 URL 中,您也会输出 HTML 内容。生成的 PDF 将与 HTML 混合,因此它变得无效。发送 PDF 时不应向浏览器发送任何 HTML 代码。这是一个可能的条件解决方案:

<?php 
require_once 'dompdf/autoload.inc.php';
use Dompdf\Dompdf;

if (isset($_GET['pdf'])) {
    ob_start(); 
}
else {
?>
<!DOCTYPE html>
<head>
<title>Country Language</title>
</head>
<body>
<form>
<?php } ?>
<table border="1"><tr><td><b>Countries Selected</b></td><td><b>Details</b></td><td><b>Amount</b></td></tr>  
    <tr>
        <td rowspan='8'><h2>Australia</h2></td>
    </tr>
    <tr>
        <td>&nbsp;Z</td>
        <td>3</td>
    </tr>
        <tr>
        <td>&nbsp;Entity</td>
        <td>&nbsp;</td>
    </tr>
    <tr>
        <td>&nbsp;N</td>
        <td>&nbsp;0</td>
    </tr>
    <tr>
        <td>English to English</td>
        <td>&nbsp;</td>
    </tr>
    <tr>
        <td>&nbsp;X</td>
        <td>&nbsp;1</td>
    </tr>
    <tr>
        <td>&nbsp;Y</td>
        <td>&nbsp;2</td>
    </tr>
    <tr>
        <td><strong>TOTAL PATENT FEE</strong></td>
        <td><b>&nbsp;USD&nbsp;1400.45</b></td>
    </tr>
    <tr>
        <td rowspan='8'><h2>India</h2></td>
    </tr>
    <tr>
        <td>&nbsp;Z</td>
        <td>3</td>
    </tr>
        <tr>
        <td>&nbsp;Entity</td>
        <td>&nbsp;Micro</td>
    </tr>
    <tr>
        <td>&nbsp;N</td>
        <td>&nbsp;1</td>
    </tr>
    <tr>
        <td>Arabic to English</td>
        <td>&nbsp;</td>
    </tr>
    <tr>
        <td>&nbsp;X</td>
        <td>&nbsp;1</td>
    </tr>
    <tr>
        <td>&nbsp;Y</td>
        <td>&nbsp;2</td>
    </tr>
    <tr>
        <td><strong>TOTAL PATENT FEE</strong></td>
        <td><b>&nbsp;USD&nbsp;315.45</b></td>
    </tr>
</table>



<?php
if (isset($_GET['pdf'])) {
  $html = ob_get_clean();
  $dompdf = new DOMPDF();
  $dompdf->load_html($html);
  $dompdf->setPaper('A4', 'portrait');
  $dompdf->render();
  $dompdf->stream("the_inquiry.pdf");
}
else {
?>
<div class="shouldPrintToPDF">
    <a href="/general/cean/cost-calc5.php?&amp;pdf=1" class="pdflink">Open as PDF</a>
</div>
</form>
</body>
</html>

<?php } ?>

您仅在发出 POST 请求并且数据可用于生成表时生成表。当您单击 PDF 链接时,会发出 GET 请求。您可以通过使用 GET 而不是 POST 发送和接收数据来解决它。 (例如:$_POST['language'] => $_GET['language'])。另一种解决方案是将 PDF 链接替换为发送必要数据的表单(它可以是带有隐藏输入字段的不可见表单)。您还应该从页面中删除其他&lt;form&gt;&lt;/form&gt; 标签(我认为它们是不必要的)。

<?php
function repopulate($field) {

    if (isset($_POST[$field])) {
        echo htmlspecialchars($_POST[$field]);
    }
}
?>
<div class="shouldPrintToPDF">
    <form method="post" action="?pdf=1">
        <input type="hidden" name="language" value="<?php repopulate('language'); ?>">
        <!-- Add all your fields (claims, pages...) here and use the repopulate function -->
        <button name="submit" type="submit">Open or save as PDF</button>
    </form>
</div>

希望对你有帮助!

【讨论】:

  • 非常感谢。让我用我的实际 PHP 脚本测试一下。
  • 当我嵌入我的实际 PHP 文件时,该脚本不起作用。但是你的脚本很好。是他们的另一种方法。如果你愿意,我可以发送我的 PHP 代码,如果你能帮我嵌入这个。
  • “不工作”是什么意思?你能告诉我你得到了什么错误吗?您可以显示整个脚本。有很多方法,但我认为最好的解决方案是使用像 Twig 这样的模板引擎来呈现 HTML 内容。你的代码会更干净。
  • 我正在修改和添加PHP脚本供您参考。单击生成 PDF 链接时出现空白页。
猜你喜欢
  • 1970-01-01
  • 2021-10-30
  • 1970-01-01
  • 2015-03-29
  • 2011-11-10
  • 1970-01-01
  • 2011-06-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多