本文詳細指導如何利用前端JavaScript庫html2pdf生成PDF文檔,并將其作為Base64編碼字符串通過ajax發送至后端php腳本。后端使用PHPMailer接收該Base64數據,解碼后將其作為附件添加到電子郵件中并發送。本教程涵蓋前端PDF生成、Ajax數據傳輸以及后端PHP解碼與PHPMailer郵件發送的全過程。
在現代web應用中,用戶經常需要將頁面內容導出為pdf并進行郵件發送。直接在客戶端保存pdf相對簡單,但若要將生成的pdf作為附件通過郵件發送,則需要將pdf數據從前端傳輸到后端。本文將詳細闡述如何結合html2pdf、ajax和phpmailer實現這一功能。
前端PDF生成與數據準備
前端的主要任務是利用html2pdf庫將指定的html元素轉換為PDF格式,并以Base64編碼的字符串形式獲取其內容。隨后,通過Ajax請求將此Base64字符串連同其他郵件相關信息發送到后端。
-
HTML元素準備 首先,確保您的HTML頁面中有一個或多個需要轉換為PDF的元素,例如一個具有特定ID的div。
<div id="printPage"> <h1>這是要導出為PDF的內容</h1> <p>這里可以包含文本、圖片、表格等。</p> <!-- 更多內容 --> </div> <button id="sendEmailBtn">生成PDF并發送郵件</button>
-
html2pdf配置與PDF內容獲取 html2pdf庫提供了output()方法,其中’datauristring’參數能夠將生成的PDF內容以數據URI(Data URI)的形式返回,該URI包含了Base64編碼的PDF數據。
// 獲取要轉換為PDF的HTML元素 let page = document.getElementById('printPage'); // html2pdf配置選項 var pdfOptions = { margin: [5, 0, 0, 0], filename: 'document.pdf', // 默認文件名,實際發送時可被后端覆蓋 image: { type: 'jpeg', quality: 1 }, pagebreak: { mode: ['legacy'] }, html2canvas: { scale: 3 }, jsPDF: { unit: 'mm', format: 'a4', orientation: 'portrait' } }; // 監聽按鈕點擊事件 $(document).on('click', '#sendEmailBtn', async function() { let pdfContent; try { // 使用await等待PDF內容生成,并獲取Base64數據URI字符串 pdfContent = await html2pdf().from(page).set(pdfOptions).outputPdf('datauristring'); // 檢查pdfContent是否成功獲取 if (pdfContent) { // 構建Ajax請求數據 let ajaxUrl = 'your_php_script.php'; // 替換為您的php腳本URL let emailTo = $("#emailTo").val(); // 假設有輸入框獲取收件人 let emailSubject = $("#emailSubject").val(); // 假設有輸入框獲取主題 let emailMessage = $("#emailMessage").val(); // 假設有輸入框獲取郵件內容 // 發送Ajax請求 $.ajax({ type: "POST", url: ajaxUrl, data: { action: "sendEmail", emailTo: emailTo, emailSubject: emailSubject, emailMessage: emailMessage, pdfContent: pdfContent // 將Base64 PDF數據發送到后端 }, success: function(response) { console.log("郵件發送響應:", response); alert("郵件發送成功!"); }, Error: function(jqXHR, textStatus, errorThrown) { console.error("郵件發送失敗:", textStatus, errorThrown); alert("郵件發送失敗!"); } }); } else { console.error("未能生成PDF內容。"); alert("未能生成PDF內容,請重試。"); } } catch (error) { console.error("生成PDF或發送郵件時發生錯誤:", error); alert("操作失敗,請檢查控制臺了解詳情。"); } });
關鍵點: outputPdf(‘datauristring’) 方法是獲取Base64編碼PDF數據的核心。由于這是一個異步操作,需要使用await或.then()來確保在發送Ajax請求之前PDF內容已經生成。
后端PHP處理與郵件發送
后端PHP腳本負責接收前端發送的Base64編碼PDF數據,對其進行解碼,然后使用PHPMailer庫將解碼后的PDF作為附件發送電子郵件。
立即學習“PHP免費學習筆記(深入)”;
-
接收與解碼PDF數據 前端發送的pdfContent是一個數據URI字符串,格式通常為data:application/pdf;base64,JVBERi…。我們需要移除前綴data:application/pdf;base64,,然后對剩余的Base64字符串進行解碼。
-
PHPMailer配置與附件發送 PHPMailer是一個功能強大的PHP郵件發送庫,支持SMTP、HTML郵件和附件等。
<?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'; // 確保是POST請求且包含pdfContent if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['pdfContent'])) { $pdfdoc = $_POST['pdfContent']; $emailTo = $_POST['emailTo'] ?? 'default@example.com'; $emailSubject = $_POST['emailSubject'] ?? '您的PDF文檔'; $emailMessage = $_POST['emailMessage'] ?? '請查收附件中的PDF文檔。'; // 從數據URI中提取Base64編碼的PDF數據 // 查找逗號的位置,然后截取后面的字符串 $pdfData = substr($pdfdoc, strpos($pdfdoc, ",") + 1); // 對Base64數據進行解碼,得到原始二進制PDF內容 $decodedPdf = base64_decode($pdfData); // 創建PHPMailer實例 $mail = new PHPMailer(true); // 啟用異常處理 try { // 服務器設置 (根據您的SMTP服務商配置) $mail->SMTPDebug = 0; // 調試輸出,0為關閉,1為客戶端,2為客戶端和服務器 $mail->isSMTP(); // 使用SMTP發送 $mail->Host = 'smtp.example.com'; // SMTP服務器地址 $mail->SMTPAuth = true; // 啟用SMTP認證 $mail->Username = 'your_email@example.com'; // SMTP用戶名 $mail->Password = 'your_password'; // SMTP密碼 $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS; // 啟用TLS加密,或者使用PHPMailer::ENCRYPTION_SMTPS $mail->Port = 587; // TLS端口通常是587,SSL端口通常是465 // 收件人設置 $mail->setFrom('your_email@example.com', '您的公司名稱'); // 發件人 $mail->addAddress($emailTo); // 收件人 // $mail->addCC('cc@example.com'); // 抄送 // $mail->addBCC('bcc@example.com'); // 密送 // 附件 // AddStringAttachment(string $string, string $filename, string $encoding = 'base64', string $type = '', string $disposition = 'attachment') // $decodedPdf是原始二進制數據,PHPMailer會自動將其編碼為Base64用于郵件傳輸 $mail->AddStringAttachment($decodedPdf, "Generated_Document.pdf", "base64", "application/pdf"); // 內容設置 $mail->isHTML(true); // 設置郵件格式為HTML $mail->Subject = $emailSubject; // 郵件主題 $mail->Body = $emailMessage; // HTML郵件內容 $mail->AltBody = strip_tags($emailMessage); // 非HTML郵件客戶端的替代內容 $mail->send(); echo json_encode(['status' => 'success', 'message' => '郵件已成功發送!']); } catch (Exception $e) { echo json_encode(['status' => 'error', 'message' => "郵件發送失敗。Mailer Error: {$mail->ErrorInfo}"]); } } else { echo json_encode(['status' => 'error', 'message' => '無效的請求或缺少PDF內容。']); } ?>
關鍵點:
- substr($pdfdoc, strpos($pdfdoc, “,”) + 1):這一行代碼用于精確地從數據URI中提取出純粹的Base64編碼字符串,移除了data:application/pdf;base64,這個前綴。
- base64_decode($pdfData):將Base64字符串解碼為原始的二進制PDF內容。
- $mail->AddStringAttachment($decodedPdf, “Generated_Document.pdf”, “base64”, “application/pdf”):這是將PDF作為附件的關鍵。$decodedPdf是解碼后的二進制數據,”Generated_Document.pdf”是附件的文件名,”base64″指定了PHPMailer在傳輸時對該二進制數據進行Base64編碼,”application/pdf”指定了MIME類型。
注意事項
- 文件大小限制: Base64編碼會使數據量增大約33%。如果生成的PDF文件非常大,可能會導致POST請求體過大,超出服務器的post_max_size或upload_max_filesize限制。您可能需要調整PHP配置或考慮將PDF先保存到服務器,然后發送文件路徑作為附件。
- 安全性:
- 錯誤處理與用戶反饋: 在前端和后端都應有健壯的錯誤處理機制。前端Ajax的error回調和后端PHPMailer的try-catch塊是必不可少的,以便及時向用戶提供反饋。
- 異步操作: html2pdf的生成過程是異步的,務必使用async/await或.then()確保在PDF內容準備好之后再進行Ajax請求。
- PHPMailer配置: PHPMailer的SMTP配置(Host, Port, Username, Password, SMTPSecure)必須與您的郵件服務提供商(如Gmail, outlook, 您的公司郵件服務器)的設置完全匹配。
- PHP文件路徑: 確保PHPMailer的require路徑正確,并且您的PHP腳本能夠訪問這些文件。
總結
通過上述步驟,您已經掌握了如何將前端html2pdf生成的PDF文檔,以Base64字符串的形式通過Ajax傳輸至后端,并利用PHPMailer將其作為電子郵件附件發送的完整流程。這種方法提供了一種靈活且強大的解決方案,使得Web應用能夠無縫地處理PDF生成和郵件發送的需求。請務必關注安全性和錯誤處理,以構建健壯可靠的系統。