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

如何用mPDF动态生成foreach循环值的表格?仅显示首个值求助

嘿,我来帮你排查这个问题!你说遍历订单数组生成PDF时始终只显示首个数据,大概率是循环逻辑、mPDF实例化时机或者变量作用域出了问题,咱们一步步拆解:

先梳理你的核心问题点

从你贴的代码来看,存在几个明显的坑:

  • 金额计算逻辑错误:你在循环外初始化$count=0,然后循环累加所有订单的金额,这会导致所有订单都用同一个总金额,而不是单个订单的金额
  • 变量拼写错误:比如$address_treet应该是$address_street,$postal_cod应该是$postal_code,这些错误会导致供应商地址为空
  • mPDF的处理逻辑缺失:你没贴出mPDF实例化和输出的代码,大概率是你要么只在循环外执行了一次输出,要么循环内没有正确重置mPDF对象
  • CSS代码截断:你提供的CSS最后到font-就断了,不完整的样式会导致PDF渲染异常

分两种需求给出修正方案

首先明确你的需求:是每个订单生成单独的PDF文件,还是所有订单的表格合并到同一个PDF里?


需求1:每个订单生成单独的PDF

这种情况需要在循环内完成「初始化mPDF→拼接当前订单HTML→输出/保存PDF」的完整流程,代码示例如下:

<?php
require_once "clientinvoice.php";
require_once __DIR__ . '/vendor/autoload.php'; // 确保引入mPDF的自动加载文件

// 遍历每个订单
foreach ($invoices as $invoice) {
    // 重置当前订单的所有变量,避免上一个订单的数据残留
    $invAmount = 0;
    $vendorAddress = '';
    $tdClass = '';
    $profomaAmount = 0;
    $restPay = 0;
    $proTrClass = 'proformaFooter';
    $thanks = '';
    $footerAddress = '';

    // 计算当前订单的金额(直接取单个订单的含税金额)
    $invAmount = number_format((float)$invoice['rate_with_vat'], 2, '.', '');

    // 获取当前订单的供应商信息
    if ($_GET['showVendor'] == 1) {
        foreach ($vendorDetails as $vendorDetail) {
            if ($vendorDetail['id'] == $invoice['vendor_id']) {
                $vendor_name = $vendorDetail['first_name'];
                $address_street = $vendorDetail['address_street'];
                $address_city = $vendorDetail['address_city'];
                $address_state = $vendorDetail['address_state'];
                $address_country = $vendorDetail['address_country'];
                $postal_code = $vendorDetail['address_postalcode'];
                break; // 找到匹配供应商后立即跳出循环,提升效率
            }
        }
        $vendorAddress = "$vendor_name, $address_street, $address_city, $address_state, $address_country, $postal_code";
        $tdClass = 'vendorDt';
    }

    // 处理形式发票逻辑(假设相关字段在当前订单数组中)
    if (!empty($invoice['proforma_invoice_amount']) && $invoice['proforma_invoice_c'] == 'yes') {
        $profomaAmount = number_format((float)$invoice['proforma_invoice_amount'], 2, '.', '');
        $resttoPay = $invoice['rate_with_vat'] - $profomaAmount;
        $restPay = number_format((float)$resttoPay, 2, '.', '');
        $proTrClass = '';
    }

    // 根据订单位置设置感谢语和页脚
    if ($invoice['client_location_c'] == 'germany') {
        $thanks = '<p>Thank you for your order</p>';
        $footerAddress = '<tr><td colspan="7" style="display:flex;justify-content:space-between;"><div class="manufacture-address"><div class="display-flex" style="text-align:center"> <div class="text-left" style="width:33%"> <p> <span>Global Guide Services GmbH</span><br> <span>Münchner Str. 23</span><br> <span>D-83703 Gmund a. Tegernsee</span><br> <span>Local Court Munich, HRB 223121</span> </p> </div> <div class="text-center" style="text-align:center;width:33%;position:absolute;bottom:0px;margin-left:60%;margin-top:-12%;"> <p> <span>Managing Director: Siavash Sartipi</span><br> <span><i class="fa fa-phone"></i> +49 151 74327305</span><br> <span><i class="fa fa-print"></i> +49 721 509663197</span><br> <span>www.global-guide-services.com</span> </p> </div> <div class="text-right" style="text-align:center;width:33%;position:absolute;bottom:0;right:10px;margin-top:-12%;" > <p> <span>VAT Nr DE 305563525</span><br> <span>Tax Nr 139/127/50609</span><br> <span>IBAN DE41 7001 0080 0697 1208 00</span><br> <span>BIC/SWIFT PBNKDEFF</span> </p> </div> </div></div></td></tr>';
    } else {
        $thanks = '<p>Intocmit de: Andreea loana</p><br/> <div class="cnp"><span>CNP: 2950318151935</span></div>';
        $footerAddress = '<tr><td colspan="7" style="text-align:center;"><div class="manufacture-address"><div class="text-center address_Raif" style="text-align:center"> <p> <span>Account holder: <label>Global Guides Services SRL,</label> Bank:Raiffeisen</span><br> <span>IBAN RO 92 RZBR 0000 0600 1754 9626 BIC(SWIFT):RZBRROBU</span><br> <span>VAT: RO34622172</span><br> </p> </div></div></td></tr>';
    }

    // 拼接当前订单的完整HTML
    $html = '
    <html>
    <head>
        <meta name="description" content="">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
        <style>
            body {
                font-family: Arial, Verdana, Helvetica, sans-serif !important;
                font-size: 14px !important;
                -webkit-print-color-adjust: exact;
                width: 960px;
                line-height:1.2 !important;
                margin: 0 auto;
            }
            table.report {
                border-collapse: collapse;
                width: 100%;
                margin: 10px 0;
            }
            .invoice-head h3 {
                text-transform: uppercase;
                margin-bottom: 5px;
                font-size: 16px;
                word-spacing: -2px;
                padding: 5px;
                border-bottom: 1px solid #ccc;
            }
            p {
                margin: 4pt 0;
            }
            td {
                vertical-align: top;
                padding: 6px;
                border: 1px solid #ccc;
            }
            table.report thead td {
                background-color: #EEEEEE;
                text-align: center;
                font-weight: bold;
            }
            .proformaFooter {
                display: none;
            }
        </style>
    </head>
    <body>
        <div class="invoice-head">
            <h3>Invoice #' . $invoice['ginvo_client_invoice_no'] . '</h3>
        </div>
        ' . ($tdClass ? '<div class="'.$tdClass.'"><p>'.$vendorAddress.'</p></div>' : '') . '
        <table class="report">
            <thead>
                <tr>
                    <td>Item</td>
                    <td>Description</td>
                    <td>Total (VAT Included)</td>
                </tr>
            </thead>
            <tbody>
                <tr>
                    <td>1</td>
                    <td>Service/Product Description</td>
                    <td>' . $invAmount . '</td>
                </tr>
                <tr class="' . $proTrClass . '">
                    <td colspan="2">Proforma Amount</td>
                    <td>' . $profomaAmount . '</td>
                </tr>
                <tr class="' . $proTrClass . '">
                    <td colspan="2">Remaining to Pay</td>
                    <td>' . $restPay . '</td>
                </tr>
            </tbody>
        </table>
        <div class="thanks">' . $thanks . '</div>
        <table class="report">
            <tfoot>' . $footerAddress . '</tfoot>
        </table>
    </body>
    </html>';

    // 初始化mPDF实例,每个订单单独创建
    $mpdf = new \Mpdf\Mpdf();
    $mpdf->WriteHTML($html);
    // 输出PDF,用订单号作为文件名区分
    $mpdf->Output('invoice-' . $invoice['ginvo_client_invoice_no'] . '.pdf', 'D');
}
?>

需求2:所有订单合并到同一个PDF

这种情况需要在循环外初始化mPDF,循环内不断累加每个订单的HTML内容(建议加分页符),最后统一输出:

<?php
require_once "clientinvoice.php";
require_once __DIR__ . '/vendor/autoload.php';

// 初始化mPDF
$mpdf = new \Mpdf\Mpdf();
$html = '';

foreach ($invoices as $invoice) {
    // 这里的变量处理逻辑和上面完全一致
    // ...(省略变量计算、HTML拼接逻辑)

    // 给每个订单添加分页符,避免内容挤在一起
    $orderHtml = '<div style="page-break-after: always;">' . $singleOrderHtml . '</div>';
    $html .= $orderHtml;
}

// 所有订单内容拼接完成后,统一写入并输出
$mpdf->WriteHTML($html);
$mpdf->Output('all-invoices.pdf', 'D');
?>

额外注意事项

  • 确保mPDF的依赖已正确安装(通过Composer安装的话,要引入autoload.php)
  • 循环内的变量一定要重置,避免上一个订单的数据污染当前订单
  • 补全所有截断的CSS代码,否则表格边框、对齐等样式会异常
  • 如果是批量生成PDF,注意服务器的内存限制,避免因订单过多导致内存溢出

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:24:10