使用 html2pdf 生成 PDF 并通过 Ajax 发送至 PHPMailer 的完整教程

使用 html2pdf 生成 PDF 并通过 Ajax 发送至 PHPMailer 的完整教程

本教程详细介绍了如何利用 JavaScripthtml2pdf 在客户端生成 PDF 文件,并将其以数据 URI 字符串的形式通过 ajax 异步发送至 php 后端。在服务器端,我们将学习如何接收并解析这份 PDF 数据,最终使用 PHPMailer 库将其作为附件发送电子邮件。文章涵盖了从前端数据准备到后端文件处理及邮件发送的完整流程,并提供了关键代码示例和注意事项。

在现代 web 应用中,用户可能需要将页面内容导出为 pdf 并通过邮件发送。直接在客户端保存 pdf 相对简单,但要将生成的 pdf 发送到服务器并作为邮件附件,则需要一套完整的客户端与服务器端协作机制。本文将详细阐述如何结合 html2pdf.JS、ajax 和 phpmailer 实现这一功能。

1. 客户端 PDF 生成与数据准备 (JavaScript)

html2pdf.js 库能够将 HTML 内容转换为 PDF。其核心在于 outputPdf() 方法,特别是当它与 ‘datauriString’ 参数结合使用时,可以将生成的 PDF 内容以 Base64 编码的字符串形式返回,这正是通过 Ajax 传输的理想格式。

首先,确保你的页面中有一个 HTML 元素作为 PDF 的内容源,例如:

<div id="printPage">     <!-- 这里是你要转换为PDF的内容 -->     <h1>报告标题</h1>     <p>这是一段示例文本,将包含在PDF中。</p>     <table>         <thead>             <tr><th>列1</th><th>列2</th></tr>         </thead>         <tbody>             <tr><td>数据A</td><td>数据B</td></tr>         </tbody>     </table> </div>

接下来是 JavaScript 代码,用于生成 PDF 字符串并准备 Ajax 请求。请注意,html2pdf() 操作是异步的,因此我们需要使用 await 或 .then() 来确保在发送 Ajax 请求之前 PDF 内容已经完全生成。

立即学习PHP免费学习笔记(深入)”;

// 获取要转换为PDF的html元素 const page = document.getElementById('printPage');  // html2pdf 配置选项 const pdfOptions = {     margin: [5, 0, 0, 0], // 上、右、下、左边距     filename: 'generated_document.pdf', // 尽管此处设置了文件名,但发送时可能需要服务器端重新指定     image: { type: 'jpeg', quality: 1 },     pagebreak: { mode: ['legacy'] }, // 分页模式     html2canvas: { scale: 3 }, // html2canvas 渲染比例     jsPDF: { unit: 'mm', format: 'a4', orientation: 'portrait' } // jsPDF 库配置 };  let pdfContent;  // 异步函数,用于生成PDF并发送Ajax请求 async function sendPdfViaAjax() {     try {         // 使用 outputPdf('datauristring') 获取Base64编码的PDF字符串         // await 确保在获取到pdfAsString后再继续执行         pdfContent = await html2pdf().from(page).set(pdfOptions).outputPdf('datauristring');          // 构建Ajax请求数据         const requestData = {             action: "sendEmail", // 服务器端用于识别操作的参数             // 其他需要发送的邮件信息,例如:             transaction: "some_transaction_data",             transactionId: "12345",             emailTo: $("#emailTo").val(),             emailCc: $("#emailCc").val(),             emailBcc: $("#emailBcc").val(),             emailSubject: $("#emailSubject").val(),             emailMessage: $("#emailMessage").val(),             pdfContent: pdfContent // 将Base64编码的PDF字符串作为参数发送         };          // 发送Ajax POST请求到后端         $.ajax({             type: "POST",             url: ajaxUrl, // 你的后端处理脚本URL             data: requestData,             success: function(response) {                 console.log("邮件发送成功:", response);                 alert("邮件已成功发送!");             },             error: function(xhr, status, error) {                 console.error("邮件发送失败:", error);                 alert("邮件发送失败,请稍后再试。");             }         });     } catch (error) {         console.error("生成PDF或发送Ajax时出错:", error);         alert("操作失败,请检查控制台信息。");     } }  // 触发发送的事件监听器,例如一个按钮点击事件 $(document).on('click', '#sendEmailBtn', function() {     sendPdfViaAjax(); });

在上述代码中,outputPdf(‘datauristring’) 是关键。它会返回一个形如 data:application/pdf;base64,JVBERi… 的字符串。这个字符串包含了 PDF 的 MIME 类型前缀和 Base64 编码的实际 PDF 数据。

2. 服务器端 PDF 处理与邮件发送 (PHP with PHPMailer)

在 PHP 后端,我们需要接收前端发送过来的 pdfContent 字符串,对其进行解析,然后使用 PHPMailer 将其作为附件添加到邮件中。

<?php // 引入PHPMailer库 use PHPMailerPHPMailerPHPMailer; use PHPMailerPHPMailerException;  // 根据你的项目结构调整路径 require 'path/to/PHPMailer/src/Exception.php'; require 'path/to/PHPMailer/src/PHPMailer.php'; require 'path/to/PHPMailer/src/SMTP.php';  // 假设这是你的Ajax处理入口 if (isset($_POST['action']) && $_POST['action'] === 'sendEmail') {     // 接收前端发送的PDF内容及其他邮件信息     $pdfdoc = $_POST['pdfContent'] ?? '';     $emailTo = $_POST['emailTo'] ?? '';     $emailCc = $_POST['emailCc'] ?? '';     $emailBcc = $_POST['emailBcc'] ?? '';     $emailSubject = $_POST['emailSubject'] ?? '无主题';     $emailMessage = $_POST['emailMessage'] ?? '无内容';      // 从data URI字符串中提取Base64编码的PDF数据     // datauristring的格式通常是: data:application/pdf;base64,实际数据     // 我们需要移除 "data:application/pdf;base64," 这部分前缀     $pdfData = substr($pdfdoc, strpos($pdfdoc, ',') + 1);      // 对Base64编码的数据进行解码     $decodedPdf = base64_decode($pdfData);      // 确保解码成功且数据不为空     if ($decodedPdf === false || empty($decodedPdf)) {         echo "Error: PDF data decoding failed.";         exit;     }      // 创建PHPMailer实例     $mail = new PHPMailer(true); // 启用异常处理      try {         // 服务器设置         $mail->SMTPDebug = 0; // 调试输出 (0 = 关闭, 1 = 客户端, 2 = 客户端和服务器)         $mail->isSMTP(); // 使用SMTP         $mail->Host = 'your.smtp.host.com'; // 你的SMTP服务器地址         $mail->SMTPAuth = true; // 启用SMTP认证         $mail->Username = 'your_smtp_username'; // SMTP 用户名         $mail->Password = 'your_smtp_password'; // SMTP 密码         $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS; // 启用TLS加密,或者 PHPMailer::ENCRYPTION_SMTPS 用于SSL         $mail->Port = 587; // TLS端口通常是587,SSL通常是465          // 收件人         $companyEmail = 'sender@yourcompany.com'; // 发件人邮箱         $companyName = 'My Company'; // 发件人名称         $mail->setFrom($companyEmail, $companyName);         $mail->addAddress($emailTo); // 收件人邮箱         if (!empty($emailCc)) {             $mail->addCC($emailCc); // 抄送         }         if (!empty($emailBcc)) {             $mail->addBCC($emailBcc); // 密送         }          // 附件         // AddStringAttachment 允许直接从字符串添加附件         // 参数: $string, $filename, $encoding, $type         $mail->AddStringAttachment($decodedPdf, "GeneratedDocument.pdf", "base64", "application/pdf");          // 内容         $mail->isHTML(true); // 邮件内容为HTML格式         $mail->Subject = $emailSubject; // 邮件主题         $mail->Body    = nl2br(htmlspecialchars($emailMessage)); // 邮件HTML内容         $mail->AltBody = strip_tags($emailMessage); // 非HTML邮件客户端的替代内容          $mail->send();         echo 'Message has been sent';     } catch (Exception $e) {         echo "Message could not be sent. Mailer Error: {$mail->ErrorInfo}";     } } else {     echo "Invalid request."; } ?>

在 PHP 代码中,有几个关键点:

  1. 数据提取: substr($pdfdoc, strpos($pdfdoc, ‘,’) + 1) 用于从 datauristring 中精确地提取出 Base64 编码的 PDF 数据,移除了 data:application/pdf;base64, 前缀。
  2. Base64 解码: base64_decode($pdfData) 将 Base64 编码的字符串解码为原始的二进制 PDF 数据。
  3. PHPMailer::AddStringAttachment: 这个方法是 PHPMailer 的一个强大功能,它允许你直接从内存中的字符串(而不是文件路径)添加附件。参数包括:
    • $string: 解码后的二进制 PDF 数据。
    • $filename: 附件在邮件中显示的文件名。
    • $encoding: 附件的编码方式,这里是 “base64″。
    • $type: 附件的 MIME 类型,这里是 “application/pdf”。

3. 注意事项与总结

  • 异步处理: html2pdf() 是异步的,务必使用 await 或 .then() 确保 PDF 内容完全生成后再进行 Ajax 请求。
  • POST 请求大小限制: Base64 编码会使数据量增大约 33%。如果 PDF 文件较大,可能会超出 PHP 服务器的 post_max_size 和 upload_max_filesize 限制。你可能需要在 php.ini 中调整这些设置。
  • 安全性: 在处理用户上传或生成的数据时,始终要注意安全。虽然 Base64 编码的 PDF 数据本身通常不包含可执行代码,但仍需确保你的 PHP 脚本对输入进行适当的验证和清理。
  • 错误处理: 前端和后端都应包含健壮的错误处理机制,以便在出现问题时能够及时发现并通知用户。
  • PHPMailer 配置: 请根据你的 SMTP 服务提供商正确配置 PHPMailer 的 Host、Port、Username、Password 和 SMTPSecure 等参数。
  • 文件命名: 在 AddStringAttachment 中指定的文件名 (“GeneratedDocument.pdf”) 是邮件客户端接收时显示的文件名,可以根据业务逻辑动态生成。

通过上述步骤,你现在应该能够成功地在客户端生成 PDF,并通过 Ajax 将其发送到 PHP 后端,最终使用 PHPMailer 作为附件发送电子邮件。这种方法避免了在服务器端生成 PDF 的额外开销,同时提供了灵活的客户端交互体验。

以上就是使用 html2pdf 生成 PDF 并通过 Ajax 发送至 PHPM

© 版权声明
THE END
喜欢就支持一下吧
点赞7 分享