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

使用 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 的内容源,例如:

报告标题

这是一段示例文本,将包含在PDF中。

列1列2
数据A数据B

接下来是 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 将其作为附件添加到邮件中。

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 代码中,有几个关键点:

数据提取: substr($pdfdoc, strpos($pdfdoc, ‘,’) + 1) 用于从 datauristring 中精确地提取出 Base64 编码的 PDF 数据,移除了 data:application/pdf;base64, 前缀。Base64 解码: base64_decode($pdfData) 将 Base64 编码的字符串解码为原始的二进制 PDF 数据。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 发送至 PHPMailer 的完整教程的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1508559.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年12月20日 04:57:00
下一篇 2025年12月20日 04:57:17

相关推荐

  • 如何用Resize Observer监听DOM元素尺寸变化?

    Resize Observer 提供高性能、精确的DOM元素尺寸监听,相比 window.onresize 具有更优的性能、细粒度控制和避免循环触发的优势,适用于自适应组件、响应式布局等场景,并需注意兼容性处理与内存管理。 Resize Observer 是一个非常实用的Web API,它允许我们以…

    2025年12月20日
    000
  • 怎么使用JavaScript操作DOM元素属性?

    操作DOM属性的核心是区分Attribute与Property:Attribute指HTML标签上的原始字符串属性,通过getAttribute、setAttribute等方法操作;Property是DOM对象的JavaScript属性,可直接访问如element.id、element.value。…

    2025年12月20日
    000
  • 如何用JavaScript实现一个支持容错处理的分布式事务?

    答案是采用Saga模式结合消息队列和幂等性设计实现分布式事务。通过将事务分解为本地操作序列,利用事件驱动机制推进流程,并在失败时执行补偿事务,确保最终一致性;编排器需持久化状态、保障消息可靠传递并处理超时与重试,以应对Node.js环境中的容错需求。 在JavaScript环境中实现一个支持容错的分…

    2025年12月20日
    000
  • JS 函数内存占用分析 – 闭包与词法环境对内存影响的实际测试

    闭包通过捕获外部变量维持状态,导致这些变量无法被垃圾回收,从而增加内存占用。测试时应使用堆快照、process.memoryUsage()等工具分析保留大小和引用链,重点关注“Retained size”及不必要的长期引用。优化策略包括:及时解除事件监听器和定时器、最小化闭包捕获的变量范围、手动置n…

    2025年12月20日
    000
  • React Native跨平台自定义模糊效果实现指南

    本文旨在解决React Native应用中@react-native-community/blur库在Android平台上存在的布局和尺寸限制问题。针对iOS平台,该库表现良好,但在Android上常导致组件不遵循约束或占据全屏。文章将详细介绍一种通过内外包装器结合BlurView组件的跨平台解决方…

    2025年12月20日
    000
  • JS 动态导入与代码分割 – 使用 import() 实现按需加载的现代方案

    动态导入(import())通过按需加载模块实现代码分割,提升首屏性能。它适用于路由级组件、大型第三方库、条件渲染组件等场景,结合构建工具生成独立chunk,优化缓存与加载优先级,支持预加载、错误处理及微前端架构,是现代前端性能优化的核心技术之一。 在前端开发中,我们总在追求更快的加载速度和更流畅的…

    2025年12月20日
    000
  • 优化WordPress区块编辑器设置加载时机:PHP过滤器的高效实践

    本文探讨在WordPress区块编辑器中修改主题提供设置的理想时机。针对JavaScript异步修改可能导致的加载时序问题,我们推荐使用PHP的block_editor_settings_all过滤器。通过在服务器端预先配置,确保设置在编辑器加载时即刻生效,从而提供更稳定、高效的用户体验。 客户端J…

    2025年12月20日
    000
  • 优化WordPress区块编辑器设置加载时机的最佳实践

    本文探讨了在WordPress区块编辑器中修改主题提供设置(如允许的区块类型)的最佳时机。针对JavaScript异步修改可能导致的加载时序问题,我们推荐使用PHP的block_editor_settings_all过滤器。这种服务器端方法确保设置在编辑器加载到前端之前即已生效,从而避免了客户端脚本…

    2025年12月20日
    000
  • Angular中将组件用作属性指令:优化表格行内容直接渲染的实践

    本文探讨了在Angular应用中,当子组件作为元素标签直接嵌套在标签内导致表格结构错误的问题。核心解决方案是利用Angular组件的灵活性,将其配置为属性指令,从而允许其模板内容直接渲染到宿主标签内部,同时保持组件逻辑和模板的模块化,有效解决了表格渲染的结构性问题。 理解问题:Angular表格渲染…

    2025年12月20日
    000
  • Angular中表格行内容直接渲染:将组件作为属性指令的最佳实践

    本教程旨在解决Angular应用中,将表格行内容封装为独立组件时,因不当嵌套导致表格渲染异常的问题。通过将子组件改造为属性指令,并将其模板内容直接渲染到标签内部,可以有效避免语义化冲突,确保表格结构正确、符合HTML规范,同时保持组件的模块化和可维护性。 1. 问题背景:组件嵌套与表格语义化冲突 在…

    2025年12月20日
    000
  • JS 移动端视频处理 – 使用 MediaRecorder API 实现视频录制与剪辑

    MediaRecorder API 为移动端视频处理提供了浏览器端录制的高效方案,通过 getUserMedia 获取音视频流并生成 Blob 文件,降低服务器依赖。结合 Canvas 可实现滤镜与叠加,配合 Web Audio API 能混音处理,利用 canvas.captureStream()…

    2025年12月20日
    000
  • jQuery中局部组件事件触发与全局类选择器优化指南

    本文探讨了在jQuery中处理多个具有相同类名的组件时,如何确保事件仅触发特定组件而非所有组件的问题。通过利用$(this)在each循环中创建局部作用域变量,并结合find()方法精确选择当前组件内部的元素,实现了事件的局部化触发。文章还进一步介绍了优化类操作的链式调用技巧,以提升代码的健壮性和可…

    2025年12月20日
    000
  • JS 函数契约编程实践 – 使用类型约束与断言验证函数前提条件

    函数契约编程通过类型约束和运行时断言确保输入输出符合预期,提升代码健壮性。使用TypeScript进行静态类型检查,结合运行时断言验证逻辑条件,可有效防止非法参数引发错误。通过封装通用断言工具或使用Zod等Schema库,能统一校验规则,增强代码可读性和维护性。JSDoc可用于非TypeScript…

    2025年12月20日
    000
  • Fancybox 弹窗与背景视频播放控制教程

    本教程详细介绍了如何在Fancybox 5.0弹窗打开时暂停页面背景视频,并在弹窗关闭时恢复背景视频播放。通过优化事件绑定机制,我们解决了初始方案中存在的延迟响应问题,确保背景视频与弹窗状态同步,显著提升用户体验。 场景描述 在网页设计中,我们经常会遇到这样的需求:页面背景播放着一段视频,同时页面上…

    2025年12月20日
    000
  • Astro 中 PrelineUI JavaScript 组件失效的解决方案

    本文旨在解决Astro项目中PrelineUI JavaScript组件(如汉堡菜单、下拉菜单)无法正常工作的问题。核心原因在于PrelineUI脚本的引用方式不正确,特别是标签中is:inline指令的误用和文件路径的错误。我们将详细介绍正确的脚本引用方法,确保PrelineUI功能在Astro环…

    2025年12月20日
    000
  • 如何用JavaScript实现一个支持多因子决策的推荐系统?

    设计可扩展评分模型需构建模块化权重与评分函数,如基于类型、演员、导演、年份等因素配置权重及匹配逻辑,利用对象结构实现灵活调整;通过数据索引、并行计算(Web Workers)、分页加载与缓存提升大数据处理效率;采用准确率、召回率、CTR、NDCG等指标结合A/B测试评估效果;应对冷启动可采用内容推荐…

    2025年12月20日
    000
  • 如何用WebNN API在浏览器中运行神经网络模型?

    WebNN API通过提供标准化接口直接调用设备AI硬件,实现浏览器内高性能、低延迟的本地AI推理。它需将预训练模型转换为ML计算图,经编译后在支持的硬件上执行,相比TF.js等方案减少中间层开销,提升效率与隐私性。当前面临模型格式兼容性、浏览器与硬件支持碎片化、调试工具不足及内存管理挑战。未来将推…

    2025年12月20日
    000
  • 解决 React Native 初始化时 FFI Gem 构建失败的指南

    本文旨在解决在 macOS 环境下使用 npx react-native init 命令初始化 React Native 项目时,因 ffi gem 无法构建原生扩展而导致的 Gem::Ext::BuildError 错误。通过安装 libffi 库并创建必要的头文件符号链接,可以确保 ffi ge…

    2025年12月20日
    000
  • Electron应用中本地文件操作与第三方库集成的最佳实践

    本文探讨了Electron应用中处理本地文件并与第三方库(如easy-template-x)集成的最佳实践。针对在渲染进程中直接访问文件系统和处理特定数据格式(如Blob或ArrayBuffer)的挑战,文章推荐将文件读取、数据处理等I/O密集型或依赖Node.js模块的操作转移到主进程执行。通过使…

    2025年12月20日
    000
  • HTML表单验证后模态框(Modal)的实现与常见问题解决

    本教程详细阐述了如何在HTML表单中实现数据验证后显示自定义模态框的功能。文章涵盖了HTML结构、CSS样式和JavaScript逻辑的协同工作,重点解决了将事件监听器正确放置以及阻止表单默认提交行为的关键问题,确保模态框在验证成功后能按预期弹出,并提供返回主页的链接。 在现代web开发中,表单提交…

    2025年12月20日
    000

发表回复

登录后才能评论
关注微信