本文详解如何正确将 mysql 数据通过 php 注入预设格式的 word 文档(含信头),避免直接 echo html 内容导致模板失效的问题,并提供安全、可维护的 docx 模板替换方案。
本文详解如何正确将 mysql 数据通过 php 注入预设格式的 word 文档(含信头),避免直接 echo html 内容导致模板失效的问题,并提供安全、可维护的 docx 模板替换方案。
直接在 PHP 中用 echo 向 .doc 或 .docx 文件输出 HTML 片段(如 <div>、<br>、<u>)是根本不可行的——Word 文档(尤其是 .docx)并非纯文本容器,而是基于 OpenXML 的 ZIP 压缩包结构,包含 document.xml、样式、字体、页眉页脚等多部分。你当前代码中的 readfile("test.doc") 输出的是二进制 DOC/DOCX 文件流,随后强行追加 HTML 标签,会严重破坏文件结构,导致 Word 无法解析,因此“内容不显示”是必然结果。
✅ 正确做法:采用模板占位符 + XML 解析替换,而非“HTML 拼接”。推荐使用成熟库 PHPWord(github.com/PHPOffice/PHPWord),它专为生成和操作 .docx 设计,支持保留原有格式(如公司信头、页眉、Logo、字体、段落样式)。
以下是完整实现步骤:
准备模板:用 Microsoft Word 创建 template.docx,在需填充处插入清晰占位符,例如:
立即学习“PHP免费学习笔记(深入)”;
[NAME] [EMAIL] [DATE]
安装 PHPWord(推荐 Composer):
composer require phpoffice/phpword
PHP 填充逻辑示例:
<?phprequire 'vendor/autoload.php';use PhpOfficePhpWordIOFactory;if (isset($_POST['NT2a'])) { // 读取模板 $phpWord = IOFactory::load('template.docx'); // 获取默认节(Section) $section = $phpWord->getSections()[0]; // 替换占位符(支持段落内、表格内、页眉等) $properties = [ 'NAME' => $_POST['name'] ?? 'N/A', 'EMAIL' => $_POST['email'] ?? 'N/A', 'DATE' => date('Y年m月d日') ]; // 执行全局替换(自动处理所有节、页眉页脚) PhpOfficePhpWordSettings::setOutputEscapingEnabled(true); $phpWord->getVariablesProcessor()->setVariable('NAME', $properties['NAME']); $phpWord->getVariablesProcessor()->setVariable('EMAIL', $properties['EMAIL']); $phpWord->getVariablesProcessor()->setVariable('DATE', $properties['DATE']); // 输出响应头 header('Content-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document'); header('Content-Disposition: attachment;filename="letter_' . date('Ymd_His') . '.docx"'); header('Cache-Control: max-age=0'); // 输出生成的文档 $objWriter = IOFactory::createWriter($phpWord, 'Word2007'); $objWriter->save('php://output'); exit;}?>
⚠️ 关键注意事项:
总结:动态生成专业 Word 文档的核心在于尊重其结构规范。放弃“HTML 思维”,转向 OpenXML 意识,借助 PHPWord 等工具,即可在保留企业信头、品牌样式的同时,高效、稳定地完成数据库驱动的文档自动化。