如何用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
相关产品推荐
相关产品推荐

