0

0

使用html2pdf生成PDF并通过Ajax发送至PHPMailer实现邮件附件功能

花韻仙語

花韻仙語

发布时间:2025-07-07 22:02:02

|

428人浏览过

|

来源于php中文网

原创

使用html2pdf生成PDF并通过Ajax发送至PHPMailer实现邮件附件功能

本教程详细阐述了如何利用前端JavaScript库html2pdf生成PDF文档,并将其以Base64编码字符串的形式通过Ajax发送至后端PHP脚本。在后端,我们使用PHPMailer库接收并解码该PDF数据,最终将其作为附件添加到电子邮件中发送。文章涵盖了从客户端PDF生成、数据传输到服务器端数据处理和邮件发送的完整流程,并提供了详细的代码示例和关键注意事项,旨在帮助开发者高效实现客户端PDF的服务器端邮件集成功能。

1. 概述

在web应用开发中,有时我们需要在客户端生成pdf文档,并将其作为附件通过电子邮件发送。直接在客户端发送邮件存在安全和功能限制,因此通常的做法是将生成的pdf数据发送到服务器,再由服务器端的邮件服务(如phpmailer)进行发送。本文将详细介绍如何结合html2pdf.js、ajax和phpmailer实现这一功能。

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

客户端的核心任务是将HTML内容转换为PDF,并以可传输的格式(通常是Base64编码字符串)获取PDF数据。html2pdf.js库提供了outputPdf('datauristring')方法来获取这种格式的数据。

2.1 html2pdf配置与PDF生成

首先,确保你的HTML页面中有一个用于生成PDF的元素,例如一个div。

<div id="printPage">
    <!-- 这里是你要转换为PDF的内容 -->
    <h1>PDF 文档标题</h1>
    <p>这是一段示例文本,将被包含在生成的PDF中。</p>
    <img src="your-image.png" alt="示例图片">
</div>
<button id="sendPdfBtn">发送PDF邮件</button>

接下来,在JavaScript中配置html2pdf并获取PDF内容:

// 假设你的HTML中有一个ID为'printPage'的元素,这是要转换为PDF的内容源
let page = document.getElementById('printPage');

// html2pdf的配置选项
var options = {
    margin: [5, 0, 0, 0], // 上右下左边距
    filename: 'document.pdf', // 默认文件名,在服务器端可覆盖
    image: {
        type: 'jpeg',
        quality: 1 // 图像质量
    },
    pagebreak: {
        mode: ['legacy'] // 分页模式
    },
    html2canvas: {
        scale: 3 // html2canvas渲染比例,影响清晰度
    },
    jsPDF: {
        unit: 'mm', // 单位
        format: 'a4', // 纸张格式
        orientation: 'portrait' // 方向:纵向
    }
};

// 监听按钮点击事件,触发PDF生成和发送
$(document).on('click', '#sendPdfBtn', async function() {
    let pdfContent;

    try {
        // 使用await等待PDF内容生成,并以datauristring格式获取
        // datauristring格式包含 "data:application/pdf;base64," 前缀
        pdfContent = await html2pdf().from(page).set(options).outputPdf('datauristring');

        // 成功获取PDF内容后,通过Ajax发送到服务器
        sendPdfToServer(pdfContent);

    } catch (error) {
        console.error("PDF生成失败:", error);
        alert("PDF生成失败,请稍后再试。");
    }
});

// 这是一个示例函数,用于将PDF内容发送到服务器
async function sendPdfToServer(pdfData) {
    // 假设ajaxUrl是你的PHP处理脚本的URL
    const ajaxUrl = 'your_php_mailer_script.php'; 

    // 其他需要发送的表单数据,例如邮件接收者、主题、消息等
    const emailTo = $("#emailTo").val(); // 假设有输入框获取收件人
    const emailSubject = $("#emailSubject").val(); // 假设有输入框获取邮件主题
    const emailMessage = $("#emailMessage").val(); // 假设有输入框获取邮件内容

    $.ajax({
        type: "POST", // 使用POST方法发送数据
        url: ajaxUrl,
        data: {
            action: "sendEmail", // 自定义动作,用于PHP脚本识别
            emailTo: emailTo,
            emailSubject: emailSubject,
            emailMessage: emailMessage,
            pdfContent: pdfData // 将Base64编码的PDF内容作为参数发送
        },
        success: function(response) {
            console.log("服务器响应:", response);
            alert("邮件发送成功!");
        },
        error: function(xhr, status, error) {
            console.error("Ajax请求失败:", status, error);
            alert("邮件发送失败,请检查网络或联系管理员。");
        }
    });
}

关键点:

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

  • outputPdf('datauristring'): 这是将PDF内容转换为Base64编码字符串的关键。它返回的字符串会包含一个data:URI前缀,例如data:application/pdf;base64,...。
  • await: html2pdf的outputPdf方法是异步的,因此需要使用await关键字(或.then()方法)来等待PDF内容生成完毕。这要求包裹该代码的函数是async函数。
  • Ajax POST请求:通过POST方法发送数据,确保PDF内容作为请求体的一部分发送,避免URL长度限制。

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

服务器端PHP脚本负责接收客户端发送的Base64编码PDF数据,解码它,然后使用PHPMailer将其作为附件发送。

Cursor
Cursor

一个新的IDE,使用AI来帮助您重构、理解、调试和编写代码。

下载

3.1 接收与解码PDF数据

当客户端通过Ajax发送pdfContent时,PHP可以通过$_POST['pdfContent']来获取它。由于datauristring包含data:application/pdf;base64,前缀,我们需要先去除这个前缀,然后再进行Base64解码。

<?php
// 引入PHPMailer类文件
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;

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'];

    // 移除data URI前缀 "data:application/pdf;base64,"
    // strpos(',', $pdfdoc) 找到第一个逗号的位置
    $pdfData = substr($pdfdoc, strpos($pdfdoc, ",") + 1); // +1是为了跳过逗号本身

    // 对Base64编码的PDF数据进行解码
    $decodedPdf = base64_decode($pdfData);

    // 获取其他邮件信息
    $emailTo = $_POST['emailTo'] ?? 'default@example.com';
    $emailSubject = $_POST['emailSubject'] ?? '来自网站的PDF附件';
    $emailMessage = $_POST['emailMessage'] ?? '请查收附件中的PDF文档。';

    // 创建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_email_password'; // SMTP密码
        $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS; // 启用TLS加密,或者PHPMailer::ENCRYPTION_SMTPS for SSL
        $mail->Port       = 587;                   // SMTP端口 (TLS通常是587,SSL通常是465)

        // 收件人
        $mail->setFrom('sender@example.com', '你的公司名称'); // 发件人邮箱和名称
        $mail->addAddress($emailTo);               // 添加收件人
        // $mail->addCC('cc@example.com');           // 添加抄送
        // $mail->addBCC('bcc@example.com');         // 添加密送

        // 附件
        // AddStringAttachment用于添加字符串作为附件
        // 第一个参数是附件内容(已解码的二进制数据)
        // 第二个参数是附件文件名
        // 第三个参数是内容的编码类型 (这里是'binary'因为我们已经解码了)
        // 第四个参数是MIME类型
        $mail->AddStringAttachment($decodedPdf, "GeneratedDocument.pdf", "binary", "application/pdf");

        // 内容
        $mail->isHTML(true);                       // 邮件内容为HTML格式
        $mail->Subject = $emailSubject;            // 邮件主题
        $mail->Body    = $emailMessage;            // 邮件HTML内容
        $mail->AltBody = strip_tags($emailMessage); // 非HTML邮件客户端的纯文本内容

        $mail->send();
        echo '邮件已成功发送!';
    } catch (Exception $e) {
        echo "邮件发送失败。 PHPMailer 错误: {$mail->ErrorInfo}";
    }
} else {
    echo '无效的请求或缺少PDF内容。';
}
?>

关键点:

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

  • Base64解码: substr($pdfdoc, strpos($pdfdoc, ",") + 1)用于去除data:application/pdf;base64,前缀。base64_decode()将剩余的Base64字符串转换为原始二进制数据。
  • AddStringAttachment: PHPMailer的AddStringAttachment()方法非常适合这种场景,因为它允许你直接从字符串添加附件内容,而无需先将文件保存到服务器。
    • 第一个参数是已解码的二进制PDF数据
    • 第三个参数"binary"至关重要,它告诉PHPMailer你提供的数据是原始二进制格式,而不是需要PHPMailer再次解码的Base64字符串。
  • PHPMailer配置: 务必根据你的SMTP服务商正确配置Host、Username、Password、SMTPSecure和Port。

4. 注意事项与最佳实践

  • 文件大小限制: 通过Ajax发送Base64编码的PDF数据,如果PDF文件过大,可能会导致POST请求体过大,超出服务器或PHP的配置限制(如post_max_size,upload_max_filesize)。对于非常大的PDF文件,考虑将文件上传到服务器的临时目录,然后将文件路径传递给PHPMailer。
  • 安全性:
    • 输入验证: 永远不要信任来自客户端的数据。对emailTo、emailSubject、emailMessage等所有接收到的POST数据进行严格的验证和过滤,以防止XSS攻击、邮件头注入等安全漏洞。
    • 文件类型验证: 虽然这里是内部生成,但如果是用户上传,应严格验证文件类型。
  • 错误处理:
    • 客户端: 在JavaScript中添加try...catch块来捕获html2pdf生成PDF时的错误,以及Ajax请求的错误。
    • 服务器端: PHPMailer的构造函数传入true可以启用异常处理,try...catch块可以捕获邮件发送过程中的错误,并通过$mail->ErrorInfo获取详细错误信息。
  • 异步操作: html2pdf的PDF生成和Ajax请求都是异步操作。确保你的JavaScript代码正确处理了这些异步性(使用async/await或.then())。
  • PHPMailer库路径: 在PHP代码中,确保require语句指向了PHPMailer库的正确路径。

5. 总结

通过结合html2pdf.js在客户端生成PDF,利用Ajax将Base64编码的PDF数据传输到服务器,再通过PHPMailer在服务器端解码并发送邮件附件,我们实现了一个完整的客户端PDF生成与服务器端邮件发送的解决方案。这种方法避免了在客户端直接处理邮件发送的复杂性和安全问题,提供了一个健壮且可扩展的实现方案。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
ajax教程
ajax教程

php中文网为大家带来ajax教程合集,Ajax是一种用于创建快速动态网页的技术。通过在后台与服务器进行少量数据交换,Ajax可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。php中文网还为大家带来ajax的相关下载资源、相关课程以及相关文章等内容,供大家免费下载使用。

166

2023.06.14

ajax中文乱码解决方法
ajax中文乱码解决方法

ajax中文乱码解决方法有设置请求头部的字符编码、在服务器端设置响应头部的字符编码和使用encodeURIComponent对中文进行编码。本专题为大家提供ajax中文乱码相关的文章、下载、课程内容,供大家免费下载体验。

170

2023.08.31

ajax传递中文乱码怎么办
ajax传递中文乱码怎么办

ajax传递中文乱码的解决办法:1、设置统一的编码方式;2、服务器端编码;3、客户端解码;4、设置HTTP响应头;5、使用JSON格式。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

124

2023.11.15

ajax网站有哪些
ajax网站有哪些

使用ajax的网站有谷歌、维基百科、脸书、纽约时报、亚马逊、stackoverflow、twitter、hacker news、shopify和basecamp等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

260

2024.09.24

require的用法
require的用法

require的用法有引入模块、导入类或方法、执行特定任务。想了解更多require的相关内容,可以阅读本专题下面的文章。

510

2023.11.27

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

761

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

221

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1569

2023.10.24

TypeScript类型系统进阶与大型前端项目实践
TypeScript类型系统进阶与大型前端项目实践

本专题围绕 TypeScript 在大型前端项目中的应用展开,深入讲解类型系统设计与工程化开发方法。内容包括泛型与高级类型、类型推断机制、声明文件编写、模块化结构设计以及代码规范管理。通过真实项目案例分析,帮助开发者构建类型安全、结构清晰、易维护的前端工程体系,提高团队协作效率与代码质量。

26

2026.03.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
10分钟--Midjourney创作自己的漫画
10分钟--Midjourney创作自己的漫画

共1课时 | 0.1万人学习

Midjourney 关键词系列整合
Midjourney 关键词系列整合

共13课时 | 0.9万人学习

AI绘画教程
AI绘画教程

共2课时 | 0.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号