使用DOMPDF将含MongoDB数据表格的PHP页面导出PDF失败如何解决
问题根源
你的代码核心问题是输出逻辑顺序错误,浏览器已经接收了HTML响应头后,无法再触发PDF下载流的响应;同时存在HTML表单嵌套的语法错误。
具体错误点
- 响应顺序倒置:你先把完整HTML输出到缓冲区并发送给浏览器,之后才判断是否要生成PDF,此时HTTP响应头已经是HTML类型,无法再修改为PDF下载类型,所以只会刷新页面。
- 缓冲区逻辑错误:把PDF生成逻辑放最前面时,还没有渲染HTML内容,抓取到的缓冲区为空,所以生成空白PDF。
- HTML语法错误:表格内的添加数据表单和外层的打印表单嵌套,不符合HTML规范,会导致提交行为异常。
- CSS缺失:你没有把表格的
.tftable样式内嵌到HTML中,dompdf无法加载外部相对路径样式,导出后会丢失样式。
修正后的代码
<?php require 'vendor/autoload.php'; use Dompdf\Dompdf; // 1. 先处理所有业务逻辑:MongoDB查询、添加数据表单提交处理 // >> 这里放你的MongoDB查询代码,查询结果存到$r变量 if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['add_data'])) { // 处理添加数据的逻辑 } // 2. 先判断是否是PDF导出请求 if (isset($_POST["pdf"])) { // 开启缓冲区抓取HTML内容 ob_start(); // 这里要内嵌CSS样式,dompdf才能识别 ?> <!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <title>Registre</title> <style> /* 把你原来的.tftable相关样式直接写在这里 */ .tftable { border-collapse: collapse; width: 100%; } .tftable th, .tftable td { border: 1px solid #ccc; padding: 8px; } </style> </head> <body> <table class="tftable"> <thead> <tr> <th>1</th> <th>2</th> <th>3</th> </tr> </thead> <tbody> <?php foreach ($r as $document): $bson = MongoDB\BSON\fromPHP($document); $json = json_decode(MongoDB\BSON\toJSON($bson)); // 注意你原来的$var1/$var2/$var3要对应取$document里的字段,确保变量已正确赋值 ?> <tr> <td><?php echo $var1 ?></td> <td><?php echo $var2 ?></td> <td><?php echo $var3 ?></td> </tr> <?php endforeach; ?> </tbody> </table> </body> </html> <?php // 获取缓冲区内容并清空缓冲区 $html = ob_get_clean(); $dompdf = new DOMPDF(); $dompdf->loadHtml($html); // 可选设置纸张大小和方向 $dompdf->setPaper('A4', 'portrait'); $dompdf->render(); // 输出PDF下载,直接终止后续代码执行避免输出多余内容 $dompdf->stream('registre.pdf', array('Attachment' => 1)); exit; } // 3. 不是PDF请求的情况下,正常输出普通页面 ?> <!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Registre</title> <style> /* 这里放你页面的完整CSS样式 */ .tftable { border-collapse: collapse; width: 100%; } .tftable th, .tftable td { border: 1px solid #ccc; padding: 8px; } </style> </head> <body> <!-- 打印表单单独放,不要和其他表单嵌套 --> <form method="post" action=""> <input type="submit" name="pdf" id="pdf" value="PRINT"> </form> <table class="tftable"> <thead> <tr> <th>1</th> <th>2</th> <th>3</th> </tr> </thead> <tbody> <?php foreach ($r as $document): $bson = MongoDB\BSON\fromPHP($document); $json = json_decode(MongoDB\BSON\toJSON($bson)); ?> <tr> <td><?php echo $var1 ?></td> <td><?php echo $var2 ?></td> <td><?php echo $var3 ?></td> </tr> <?php endforeach; ?> </tbody> </table> <!-- 添加数据表单单独放,不要嵌套 --> <form action="" method="POST"> <table class="tftable"> <tr> <td> <label for="var1">var1</label><br> <input type="date" id="var1" name="var1"> </td> <td> <label for="var2">var2</label><br> <input type="text" id="var2" name="var2"> </td> <td> <label for="var3">var3</label><br> <input type="text" id="var3" name="var3"> </td> </tr> <tr> <td> <input type="submit" value="Add Data" name="add_data"> </td> </tr> </table> </form> </body> </html>
额外注意事项
- dompdf不支持太新的CSS3属性,复杂样式建议降级写兼容写法。
- 如果生成PDF出现中文乱码,需要自行安装dompdf支持的中文字体并在CSS中指定字体。
内容的提问来源于stack exchange,提问作者AxelJarni
相关产品推荐
相关产品推荐

