You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在mPDF(PHP)中一键批量在新标签页打印多份PDF

解决mPDF生成多份PDF并逐个在新标签页打开的问题

你的问题核心在于单个请求中调用$mpdf->Output()后,后续代码无法执行,因为这个方法会直接发送PDF的二进制响应和HTTP头,浏览器收到后就会终止当前请求的处理,后续的JS跳转/PHP包含逻辑根本跑不起来。另外用Session计数的方式也不可靠,因为每个新标签的请求是独立的,Session状态同步容易出问题。

下面是重构后的可行方案:

思路调整

把「单个请求循环生成所有PDF」改成「前端逐个请求单份PDF接口,每个请求对应一个新标签页」,让每个PDF都由独立的HTTP请求生成,避免响应冲突。

1. 单份PDF生成接口(get_pdf.php)

负责接收单个模型参数,生成并输出对应的PDF:

<?php
// 数据库连接配置
$servername = "你的服务器地址";
$username = "数据库用户名";
$password = "数据库密码";
$dbname = "数据库名称";

// 建立安全连接
$conn = mysqli_connect($servername, $username, $password, $dbname);
if (!$conn) die("连接失败: " . mysqli_connect_error());

require_once __DIR__ . '/vendor/autoload.php';

// 获取请求参数并防SQL注入
if (!isset($_GET['model'])) die("缺少必要参数");
$safeModel = mysqli_real_escape_string($conn, $_GET['model']);

// 查询对应模型的数据
$query = "SELECT * FROM Hardware WHERE Model = '$safeModel'";
$result = mysqli_query($conn, $query);

$mpdf = new \Mpdf\Mpdf();

if (mysqli_num_rows($result) > 0) {
    $row = mysqli_fetch_assoc($result);
    $bullets = explode("|", $row["Bullets"]);
    foreach ($bullets as $item) {
        // 转义HTML特殊字符避免格式错乱
        $mpdf->WriteHTML('<font style="font-size:9px; font-family:Calibri"><b>•</b> '. htmlspecialchars($item) .' </font><br>');
    }
} else {
    $mpdf->WriteHTML('<p style="font-size:9px; font-family:Calibri">0 results</p>');
}

// 以inline方式在浏览器中打开PDF
$mpdf->Output('', 'I');
mysqli_close($conn);
?>

2. 前端触发页面(index.php)

先从数据库获取所有需要生成PDF的模型,再通过JS逐个打开新标签请求接口:

<?php
// 连接数据库获取所有需要处理的模型
$servername = "你的服务器地址";
$username = "数据库用户名";
$password = "数据库密码";
$dbname = "数据库名称";

$conn = mysqli_connect($servername, $username, $password, $dbname);
if (!$conn) die("连接失败: " . mysqli_connect_error());

$query = "SELECT DISTINCT Model FROM Hardware";
$result = mysqli_query($conn, $query);
$models = [];
while ($row = mysqli_fetch_assoc($result)) {
    $models[] = $row['Model'];
}
mysqli_close($conn);
?>
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>批量生成PDF</title>
</head>
<body>
<script>
window.onload = function() {
    const models = <?php echo json_encode($models); ?>;
    // 延迟打开新标签,避免浏览器拦截弹窗
    models.forEach((model, index) => {
        setTimeout(() => {
            window.open(`get_pdf.php?model=${encodeURIComponent(model)}`, '_blank');
        }, index * 500); // 每500ms打开一个标签,可根据需求调整
    });
};
</script>
</body>
</html>

为什么原来的方案不行?

  • $mpdf->Output()会直接发送PDF的响应头和二进制内容,一旦执行,当前PHP请求的后续代码(包括include 'caller.php')都会被浏览器忽略,因为HTTP响应已经完成。
  • 用Session计数的方式不可靠:每个新标签的请求是独立的,Session的更新不会实时同步,容易出现计数混乱的情况。
  • 浏览器有弹窗拦截机制,一次性打开多个标签很容易被拦截,延迟打开能降低被拦截的概率。

注意事项

  • 务必做好SQL注入防护,示例中用了mysqli_real_escape_string,更安全的方式是使用预处理语句。
  • 如果浏览器仍然拦截弹窗,需要提示用户手动允许当前站点的弹窗权限。
  • 可以根据服务器性能和浏览器承受能力调整标签打开的间隔时间。

内容的提问来源于stack exchange,提问作者Harish_Pradhan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 08:53:22