0

0

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

霞舞

霞舞

发布时间:2025-07-07 21:32:01

|

648人浏览过

|

来源于php中文网

原创

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

本教程详细介绍了如何利用 JavaScript 库 html2pdf 在客户端生成 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 内容已经完全生成。

// 获取要转换为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 数据。

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

GentleAI
GentleAI

GentleAI是一个高效的AI工作平台,为普通人提供智能计算、简单易用的界面和专业技术支持。让人工智能服务每一个人。

下载

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

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

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

// 假设这是你的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 的额外开销,同时提供了灵活的客户端交互体验。

热门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

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

1051

2023.08.02

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号