HTML转PDF并用Ajax发送给PHPMailer教程
在文章实战开发的过程中,我们经常会遇到一些这样那样的问题,然后要卡好半天,等问题解决了才发现原来一些细节知识点还是没有掌握好。今天golang学习网就整理分享《HTML2PDF生成PDF并用Ajax发送给PHPMailer的教程》,聊聊,希望可以帮助到正在努力赚钱的你。

1. 概述与准备工作
在Web应用中,有时我们需要将用户界面上的内容转换为PDF文档,并将其通过邮件发送。直接在客户端生成并发送邮件是不安全的,也无法实现。因此,常见的做法是:在客户端生成PDF的二进制数据(通常是Base64编码),通过Ajax发送到服务器,再由服务器端脚本(如PHP)处理并发送邮件。
本教程将使用以下关键技术栈:
- 前端: html2pdf.js (基于html2canvas和jsPDF) 用于将HTML内容转换为PDF,jQuery 或原生 XMLHttpRequest 进行Ajax通信。
- 后端: PHP 处理数据,PHPMailer 库发送电子邮件。
在开始之前,请确保你的项目已引入 html2pdf.js 和 jQuery (如果使用),并且服务器端已安装 PHPMailer。
2. 客户端:生成PDF并以Base64字符串形式传输
在客户端,我们首先使用html2pdf.js将指定的HTML元素内容转换为PDF。关键在于不直接保存PDF,而是将其输出为Base64编码的URI字符串。
2.1 HTML结构准备
确保你的HTML页面中有一个包含需要转换为PDF内容的元素,例如:
<div id="printPage">
<h1>这是一个PDF标题</h1>
<p>这是需要转换为PDF的内容。</p>
<ul>
<li>列表项1</li>
<li>列表项2</li>
</ul>
<img src="your_image.png" alt="示例图片">
</div>
<button id="sendPdfBtn">生成并发送PDF</button>2.2 JavaScript代码:生成Base64 PDF并发送Ajax请求
html2pdf.js 提供了一个 output() 方法,可以指定输出格式。我们使用 datauristring 格式来获取PDF的Base64编码字符串。
// 获取需要转换为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 // html2canvas 渲染比例
},
jsPDF: {
unit: 'mm', // 单位
format: 'a4', // 纸张格式
orientation: 'portrait' // 方向:纵向
}
};
// 监听按钮点击事件
$(document).on('click', '#sendPdfBtn', async function() {
let pdfContent;
try {
// 使用 await 等待 PDF 生成为 datauristring
pdfContent = await html2pdf().from(page).set(pdfOptions).outputPdf('datauristring');
// 或者使用 .then() 回调方式
// await html2pdf().from(page).set(pdfOptions).outputPdf('datauristring').then(function(pdfAsString) {
// pdfContent = pdfAsString;
// });
// 准备 Ajax 请求数据
let ajaxUrl = 'your_php_mailer_script.php'; // 替换为你的PHP脚本URL
let transaction = 'someTransactionType'; // 示例数据
let transactionId = '12345'; // 示例数据
$.ajax({
type: "POST",
url: ajaxUrl,
data: {
action: "sendEmail", // 示例动作
transaction: transaction,
transactionId: transactionId,
emailTo: $("#emailTo").val() || "recipient@example.com", // 接收者邮箱
emailCc: $("#emailCc").val(), // 抄送
emailBcc: $("#emailBcc").val(), // 密送
emailSubject: $("#emailSubject").val() || "来自网站的PDF报告", // 邮件主题
emailMessage: $("#emailMessage").val() || "请查收附件中的PDF文档。", // 邮件内容
pdfContent: pdfContent // 核心:Base64编码的PDF内容
},
success: function(data) {
console.log("邮件发送响应:", data);
alert("邮件发送成功!");
},
error: function(xhr, status, error) {
console.error("Ajax请求失败:", status, error);
alert("邮件发送失败,请查看控制台了解详情。");
}
});
} catch (error) {
console.error("PDF生成或发送过程中发生错误:", error);
alert("PDF生成或发送失败。");
}
});代码解释:
- html2pdf().from(page).set(pdfOptions).outputPdf('datauristring'): 这是核心部分。它指示 html2pdf 从 page 元素生成PDF,应用 pdfOptions 配置,并将结果输出为 datauristring。
- datauristring 格式通常是 data:application/pdf;base64,JVBERi...,其中 JVBERi... 是PDF的Base64编码内容。服务器端需要处理这个前缀。
- await 关键字用于等待异步的 html2pdf 操作完成。为了使用 await,你的函数需要被声明为 async。
- $.ajax() 用于发送POST请求,将 pdfContent 作为数据的一部分发送到服务器。
3. 服务器端:处理Base64 PDF数据并使用PHPMailer发送邮件
在服务器端(PHP脚本),我们将接收前端发送过来的Base64字符串,进行解码,然后使用PHPMailer将其作为附件发送。
3.1 PHP代码:接收、解码并发送邮件
<?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';
// 设置响应头,防止CORS问题或确保JSON响应
header('Content-Type: application/json');
// 检查是否是POST请求
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
echo json_encode(['status' => 'error', 'message' => 'Invalid request method.']);
exit;
}
// 获取前端发送的PDF内容及其他邮件信息
$pdfdoc = $_POST['pdfContent'] ?? '';
$emailTo = $_POST['emailTo'] ?? '';
$emailCc = $_POST['emailCc'] ?? '';
$emailBcc = $_POST['emailBcc'] ?? '';
$emailSubject = $_POST['emailSubject'] ?? '邮件主题未设置';
$emailMessage = $_POST['emailMessage'] ?? '邮件内容为空';
// 验证PDF内容是否存在
if (empty($pdfdoc)) {
echo json_encode(['status' => 'error', 'message' => 'PDF content is missing.']);
exit;
}
// 提取Base64编码的PDF数据
// 'data:application/pdf;base64,' 这个前缀需要被移除
$pdfData = substr($pdfdoc, strpos($pdfdoc, ',') + 1); // 从逗号后面开始截取
// 对Base64数据进行解码
$decodedPdf = base64_decode($pdfData);
// 检查解码是否成功
if ($decodedPdf === false) {
echo json_encode(['status' => 'error', 'message' => 'Failed to decode PDF content.']);
exit;
}
// PHPMailer 实例
$mail = new PHPMailer(true); // true enables exceptions
try {
// 服务器设置 (根据你的SMTP服务商配置)
$mail->SMTPDebug = 0; // 0 = off (for production), 1 = client messages, 2 = client and server messages
$mail->isSMTP(); // 使用SMTP
$mail->Host = 'smtp.yourdomain.com'; // SMTP 服务器地址
$mail->SMTPAuth = true; // 启用SMTP认证
$mail->Username = 'your_email@yourdomain.com'; // SMTP 用户名
$mail->Password = 'your_email_password'; // SMTP 密码
$mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS; // 启用TLS加密,或者 PHPMailer::ENCRYPTION_SMTPS for SSL
$mail->Port = 587; // TLS 端口通常是 587,SSL 端口通常是 465
// 收件人
$mail->setFrom('sender@yourdomain.com', 'Your Company Name'); // 发件人邮箱和名称
$mail->addAddress($emailTo); // 收件人邮箱
if (!empty($emailCc)) {
$mail->addCC($emailCc); // 抄送
}
if (!empty($emailBcc)) {
$mail->addBCC($emailBcc); // 密送
}
// 附件
// AddStringAttachment(string $string, string $filename, string $encoding = 'base64', string $type = '', string $disposition = 'attachment')
// 这里我们传入的是原始的二进制PDF数据,所以编码类型是 'base64' (因为它之前是base64编码的),MIME类型是 'application/pdf'
$mail->AddStringAttachment($decodedPdf, "GeneratedDocument.pdf", "base64", "application/pdf");
// 内容
$mail->isHTML(true); // 邮件内容为HTML格式
$mail->Subject = $emailSubject; // 邮件主题
$mail->Body = nl2br(htmlspecialchars($emailMessage)); // 邮件HTML内容,nl2br保留换行,htmlspecialchars防止XSS
$mail->AltBody = strip_tags($emailMessage); // 纯文本内容,用于不支持HTML的邮件客户端
$mail->send();
echo json_encode(['status' => 'success', 'message' => 'Message has been sent.']);
} catch (Exception $e) {
echo json_encode(['status' => 'error', 'message' => "Message could not be sent. Mailer Error: {$mail->ErrorInfo}"]);
}
?>代码解释:
- PHPMailer 引入: 确保 require 语句指向你的PHPMailer库的正确路径。
- 数据提取: $_POST['pdfContent'] 获取前端发送的Base64字符串。
- substr($pdfdoc, strpos($pdfdoc, ',') + 1): 这是关键一步。datauristring 格式包含一个前缀(例如 data:application/pdf;base64,),我们需要用 strpos 找到逗号的位置,然后用 substr 从逗号之后开始截取,从而得到纯粹的Base64编码数据。
- base64_decode($pdfData): 将纯粹的Base64编码数据解码回原始的二进制PDF数据。
- $mail->AddStringAttachment(...): 这是PHPMailer中用于添加字符串作为附件的方法。
- 第一个参数 $decodedPdf 是解码后的二进制PDF数据。
- 第二个参数 "GeneratedDocument.pdf" 是附件的文件名。
- 第三个参数 "base64" 表示附件的编码方式(尽管我们传入的是解码后的数据,PHPMailer内部会根据这个参数进行处理,这里指明原始数据是Base64编码的)。
- 第四个参数 "application/pdf" 是附件的MIME类型,这非常重要,它告诉邮件客户端这是一个PDF文件。
- SMTP 配置: 替换 host, username, password, port, SMTPSecure 为你的SMTP服务器的实际配置。
- 错误处理: try...catch 块用于捕获PHPMailer可能抛出的异常,并返回详细的错误信息。
4. 注意事项与总结
- 文件大小限制: 通过Ajax发送Base64编码的数据会显著增加数据量(Base64编码会使数据量增大约33%)。对于非常大的PDF文件,这可能会导致HTTP请求体过大,超出服务器或Web服务器(如Nginx, Apache)的请求体大小限制。你可能需要调整服务器配置(例如PHP的 post_max_size 和 upload_max_filesize,以及Web服务器的 client_max_body_size)。
- 安全性:
- 始终在服务器端验证所有接收到的输入数据,包括邮件地址、主题和内容,以防止注入攻击(如XSS)。
- 不要直接暴露你的SMTP凭据在客户端代码中。PHPMailer配置应完全在服务器端进行。
- 考虑对生成的PDF内容进行服务器端验证或消毒,如果内容来源于用户输入。
- 异步操作: html2pdf 的生成过程是异步的。确保你在发送Ajax请求之前,PDF内容已经完全生成并赋值给 pdfContent 变量。使用 await 或 .then() 回调是处理异步操作的正确方式。
- MIME 类型: 在 AddStringAttachment 中正确指定 application/pdf MIME 类型至关重要,它能确保邮件客户端正确识别并显示附件。
- 调试: 在开发阶段,将 PHPMailer 的 SMTPDebug 设置为 1 或 2 可以帮助你查看SMTP通信过程,从而诊断连接或认证问题。在生产环境中,务必将其设置为 0。
- PHPMailer 路径: 确保 require 语句中PHPMailer库的路径是正确的。
通过以上步骤,你就可以成功地在客户端生成PDF,并通过Ajax将其发送到服务器,再由PHPMailer将其作为附件发送电子邮件。这种方法兼顾了客户端生成PDF的灵活性和服务器端发送邮件的可靠性与安全性。
以上就是本文的全部内容了,是否有顺利帮助你解决问题?若是能给你带来学习上的帮助,请大家多多支持golang学习网!更多关于文章的相关知识,也可关注golang学习网公众号。
AI剪辑能替代导演吗?未来趋势解析
- 上一篇
- AI剪辑能替代导演吗?未来趋势解析
- 下一篇
- Python词云生成教程:wordcloud使用详解
-
- 文章 · 前端 | 4分钟前 |
- CSScolor-mix函数详解与使用技巧
- 283浏览 收藏
-
- 文章 · 前端 | 22分钟前 | Chrome开发者工具 堆快照 JavaScript内存泄漏 引用关系 分离DOM节点
- JavaScript内存泄漏分析及堆快照使用技巧
- 476浏览 收藏
-
- 文章 · 前端 | 32分钟前 |
- 网页转PDF无库方案全解析
- 266浏览 收藏
-
- 文章 · 前端 | 47分钟前 |
- CSS响应式侧边栏实现方法
- 314浏览 收藏
-
- 文章 · 前端 | 59分钟前 |
- ES6类处理嵌套API数据教程
- 123浏览 收藏
-
- 文章 · 前端 | 1小时前 |
- JavaScript迭代器模式:自定义遍历方法
- 262浏览 收藏
-
- 文章 · 前端 | 1小时前 |
- CSShoveractivetransition实战技巧
- 181浏览 收藏
-
- 文章 · 前端 | 1小时前 |
- JavaScript深浅拷贝原理与实现解析
- 226浏览 收藏
-
- 文章 · 前端 | 1小时前 | JavaScript 异步加载 Script标签 内联脚本 外部脚本
- HTML中script标签加载JS方法详解
- 422浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- ChatExcel酷表
- ChatExcel酷表是由北京大学团队打造的Excel聊天机器人,用自然语言操控表格,简化数据处理,告别繁琐操作,提升工作效率!适用于学生、上班族及政府人员。
- 3203次使用
-
- Any绘本
- 探索Any绘本(anypicturebook.com/zh),一款开源免费的AI绘本创作工具,基于Google Gemini与Flux AI模型,让您轻松创作个性化绘本。适用于家庭、教育、创作等多种场景,零门槛,高自由度,技术透明,本地可控。
- 3416次使用
-
- 可赞AI
- 可赞AI,AI驱动的办公可视化智能工具,助您轻松实现文本与可视化元素高效转化。无论是智能文档生成、多格式文本解析,还是一键生成专业图表、脑图、知识卡片,可赞AI都能让信息处理更清晰高效。覆盖数据汇报、会议纪要、内容营销等全场景,大幅提升办公效率,降低专业门槛,是您提升工作效率的得力助手。
- 3446次使用
-
- 星月写作
- 星月写作是国内首款聚焦中文网络小说创作的AI辅助工具,解决网文作者从构思到变现的全流程痛点。AI扫榜、专属模板、全链路适配,助力新人快速上手,资深作者效率倍增。
- 4554次使用
-
- MagicLight
- MagicLight.ai是全球首款叙事驱动型AI动画视频创作平台,专注于解决从故事想法到完整动画的全流程痛点。它通过自研AI模型,保障角色、风格、场景高度一致性,让零动画经验者也能高效产出专业级叙事内容。广泛适用于独立创作者、动画工作室、教育机构及企业营销,助您轻松实现创意落地与商业化。
- 3824次使用
-
- JavaScript函数定义及示例详解
- 2025-05-11 502浏览
-
- 优化用户界面体验的秘密武器:CSS开发项目经验大揭秘
- 2023-11-03 501浏览
-
- 使用微信小程序实现图片轮播特效
- 2023-11-21 501浏览
-
- 解析sessionStorage的存储能力与限制
- 2024-01-11 501浏览
-
- 探索冒泡活动对于团队合作的推动力
- 2024-01-13 501浏览

