You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP/Laravel如何读取PDF/DOC/DOCX内容带样式嵌入邮件正文

实现方案

首先明确核心逻辑:邮件客户端原生不支持直接渲染PDF、DOC、DOCX格式的文件内容,你需要先将目标文档转换为带内联样式的HTML格式,再嵌入到邮件的HTML正文块中,就能实现保留原有样式展示的效果。

通用转换方案

推荐使用服务器端安装LibreOffice的方式实现三类文档的统一转换,兼容性最好,格式保留完整:

  • 服务器安装LibreOffice后,可直接调用命令行完成任意格式转HTML:
    命令示例:libreoffice --headless --convert-to html --outdir 输出目录路径 源文件路径
  • 转换完成后读取生成的HTML文件内容,再使用emogrifier类库将HTML中的CSS样式全部转换为元素内联样式,避免邮件客户端屏蔽头部样式导致格式错乱
  • 如果文档中包含图片,转换时需要将图片转成base64编码内嵌到HTML中,避免邮件客户端默认不加载外链图片导致丢失内容。

代码修改示例

你原有的邮件发送逻辑基本不用改,只需要在之前新增文档转HTML的逻辑,将转换得到的HTML内容赋值给$message变量即可,参考代码:

// 新增:文档转HTML逻辑
$filePath = 'path/to/my/file.pdf'; // 支持pdf/doc/docx
$ext = strtolower(pathinfo($filePath, PATHINFO_EXTENSION));
$outputDir = 'path/to/temp/dir/';
$htmlPath = $outputDir . pathinfo($filePath, PATHINFO_FILENAME) . '.html';

// 调用LibreOffice转换
exec("libreoffice --headless --convert-to html --outdir {$outputDir} {$filePath} 2>&1", $output, $returnVar);
if ($returnVar !== 0) {
    // 转换失败处理逻辑
    return false;
}

// 读取转换后的HTML内容,处理样式内联
$docHtml = file_get_contents($htmlPath);
// 这里可以引入emogrifier处理样式内联,示例省略处理逻辑
$message = $docHtml; // 替换原有的邮件正文内容

// 以下是你原有的发送逻辑,基本不用改动
$uid = md5(uniqid(time()));
$file_name = basename($filePath);

// header
$header = "From: Support <info@support.com>\r\n";
$header .= "Reply-To: info@support.com \r\n";
$header .= "MIME-Version: 1.0\r\n";
$header .= "Content-Type: multipart/mixed; boundary=\"".$uid."\"\r\n\r\n";

// message & attachment
$nmessage = "--".$uid."\r\n";
$nmessage .= "Content-type:text/html; charset=\"utf-8\"\r\n"; // 建议把编码换成utf-8避免中文乱码
$nmessage .= "Content-Transfer-Encoding: 7bit\r\n\r\n";
$nmessage .= $message."\r\n\r\n";
// 如果不需要保留附件可以删掉下面附件拼接的逻辑
$content = chunk_split(base64_encode(file_get_contents($filePath)));
$nmessage .= "--".$uid."\r\n";
$nmessage .= "Content-Type: application/octet-stream; name=\"".$file_name."\"\r\n";
$nmessage .= "Content-Transfer-Encoding: base64\r\n";
$nmessage .= "Content-Disposition: attachment; filename=\"".$file_name."\"\r\n\r\n";
$nmessage .= $content."\r\n\r\n";
$nmessage .= "--".$uid."--";

if (mail($mailto, $subject, $nmessage, $header))
    return true;
else
    return false;

可选分格式处理方案

如果不想装LibreOffice,也可以分格式用PHP库处理:

  • DOC/DOCX:使用PhpOffice/PHPWord库读取文档内容,直接调用$writer = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, 'HTML');方法输出HTML
  • PDF:使用Poppler工具集的pdftohtml命令行转换,或者用本地PDF解析库处理

注意事项

  • 务必将所有样式转为内联样式,否则Outlook、QQ邮箱等客户端会丢失格式
  • 转换后的HTML建议做精简处理,删除冗余标签,避免邮件体积过大被判定为垃圾邮件
  • 编码统一用UTF-8,避免多语言内容乱码

内容的提问来源于stack exchange,提问作者ItWorksOnLocal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 02:09:02