使用PHPMailer、PHPSpreadsheet与DOMPdf时遇setPaper()方法未定义错误求助
解决Dompdf报错Call to undefined method Dompdf\Options::setPaper()及邮件发送问题
核心报错原因
Dompdf 2.0及以上版本已移除setPaper()方法,替代方案有两种:
- 分别调用
setDefaultPaperSize()设置纸张规格(如letter)和setDefaultPaperOrientation()设置纸张方向(如portrait) - 直接通过数组初始化Options对象
代码中的其他问题及修正
除了Dompdf的方法兼容问题,你的代码还有几处逻辑错误需要调整:
- PhpSpreadsheet生成PDF逻辑错误:错误调用了Dompdf的
loadHtml方法,PhpSpreadsheet的Dompdf Writer会自动处理Excel转PDF,无需手动加载HTML - PHPMailer循环重置问题:每次循环发送邮件后,未清除之前的收件人和附件,会导致后续邮件携带历史内容
- 变量未定义问题:邮件结果输出中的
$to变量未定义,需替换为实际的会员邮箱
修正后的完整代码
require_once 'vendor/autoload.php'; use PhpOffice\PhpSpreadsheet\IOFactory; use PhpOffice\PhpSpreadsheet\Writer\Pdf\Dompdf; use Dompdf\Options; use PHPMailer\PHPMailer\PHPMailer; use PHPMailer\PHPMailer\Exception; // 获取表单提交的年份 $year = $_POST['year']; // 获取对应年份的会员捐赠数据 $members = getMemberDonations($year); // 初始化PHPMailer(移到循环外避免重复初始化) $mail = new PHPMailer(true); // 启用异常处理便于调试 try { // 配置SMTP参数 $mail->isSMTP(); $mail->Host = 'smtp.gmail.com'; $mail->SMTPAuth = true; $mail->Username = 'liccftest@gmail.com'; $mail->Password = 'citgxpzhmtoticrv'; $mail->SMTPSecure = 'tls'; $mail->Port = 587; $mail->setFrom('liccftest@gmail.com', 'LICCF'); // 邮件模板 $body = 'Dear {first} {last},<br><br>' . 'Thank you for your donation of ${amount} to LICCFTaxReceipt in {year}.<br>' . 'Please find attached your tax receipt for this donation.<br><br>' . 'Sincerely,<br>LICCFTaxReceipt Team'; foreach ($members as $member) { $variables = [ '{first}' => $member['f_name'], '{last}' => $member['l_name'], '{address}' => $member['address'], '{city}' => $member['city'], '{province}' => $member['province'], '{postal}' => $member['postal_code'], '{amount}' => $member['total_amount'], '{year}' => $year, '{email}' => $member['email'], ]; // 加载Excel模板 $spreadsheet = IOFactory::load('receipt template.xlsx'); $worksheet = $spreadsheet->getActiveSheet(); // 替换单元格变量 foreach ($worksheet->getRowIterator() as $row) { foreach ($row->getCellIterator() as $cell) { $value = $cell->getValue(); foreach ($variables as $variable => $replacement) { $value = str_replace($variable, $replacement, $value); } $cell->setValue($value); } } // 配置Dompdf选项(二选一即可) // 方式一:数组初始化 $options = new Options([ 'defaultPaperSize' => 'letter', 'defaultPaperOrientation' => 'portrait' ]); // 方式二:调用新方法 // $options = new Options(); // $options->setDefaultPaperSize('letter'); // $options->setDefaultPaperOrientation('portrait'); // 初始化PhpSpreadsheet的Dompdf Writer并生成PDF $writer = new Dompdf($spreadsheet, $options); $pdfContent = $writer->getContent(); // 保存PDF到磁盘(可选) $fileName = "LICCFTaxReceipt_{$member['f_name']}_{$member['l_name']}_{$year}.pdf"; file_put_contents($fileName, $pdfContent); // 重置PHPMailer收件人和附件 $mail->clearAddresses(); $mail->clearAttachments(); // 设置当前邮件信息 $mail->addAddress($member['email']); $mail->Subject = "Tax Receipt for your donation to LICCFTaxReceipt for the year of {$year}"; $mail->Body = str_replace(array_keys($variables), array_values($variables), $body); $mail->isHTML(true); // 启用HTML格式 $mail->addStringAttachment($pdfContent, $fileName); // 发送邮件 $mail->send(); echo "Email sent successfully to {$member['email']}<br>"; } } catch (Exception $e) { echo "Mailer Error: {$mail->ErrorInfo}<br>"; } catch (\PhpOffice\PhpSpreadsheet\Exception $e) { echo "Spreadsheet Error: {$e->getMessage()}<br>"; } catch (\Dompdf\Exception $e) { echo "Dompdf Error: {$e->getMessage()}<br>"; }
关键修改说明
- Dompdf配置兼容:用新版本支持的方式设置纸张参数
- PDF生成逻辑修正:利用PhpSpreadsheet Writer的原生方法直接生成PDF内容
- PHPMailer循环清理:每次循环重置收件人和附件,避免内容混乱
- 异常捕获优化:覆盖邮件、表格、PDF生成三个环节的异常,便于定位问题
- 文件名优化:添加会员姓名避免文件覆盖
内容的提问来源于stack exchange,提问作者Donavon04
相关产品推荐
相关产品推荐

