PHP文档生成需依场景选稳定方案:Dompdf需用load_font.php处理中文字体并显式声明;Word转PDF应优先用libreoffice命令行;Excel导出推荐PhpSpreadsheet避免CSV陷阱;Word文档必须用PHPWord生成标准.docx。

PHP本身不内置任何文档生成能力,所有PDF、Excel、Word操作都依赖第三方库或系统工具。选错方案会导致中文乱码、样式崩坏、内存溢出或部署失败——关键不在“能不能做”,而在“在哪种场景下用哪个最稳”。
Dompdf渲染HTML为PDF时中文显示异常
Dompdf不支持直接加载.ttf字体文件,把simhei.ttf丢进lib/fonts/目录毫无作用。必须用它自带的load_font.php工具生成PHP字体描述文件(如simhei.ufm和simhei.phpt),再通过add_font()注册。
- 执行命令前确认PHP CLI版本与Web一致:
php vendor/dompdf/dompdf/load_font.php simhei /path/to/simhei.ttf - 生成后将
.ufm和.phpt文件放入lib/fonts/,并在代码中调用$dompdf->getFontMetrics()->registerFont(['family' => 'simhei', 'style' => 'normal', 'file' => __DIR__.'/lib/fonts/simhei.ufm']) - HTML中必须显式声明字体:
<body style="font-family: simhei;">,否则默认用DejaVu Sans,中文仍会显示为方块 - 若页面含远程图片(如
<img src="https://example.com/logo.png">),需提前启用:$dompdf->set_option('isRemoteEnabled', true)
用PHPWord + Dompdf转换.docx为PDF时表格错位
PHPWord的HtmlWriter只是简单地把Word结构转成语义模糊的HTML标签,<table>可能被拆成多个<div>,CSS类名丢失,colspan/rowspan被忽略。这不是Dompdf的问题,而是中间环节失真。
- 不要对含合并单元格、嵌套表格或页眉页脚的Word文档走“Word → HTML → PDF”链路
- 复杂文档优先走
libreoffice --headless --convert-to pdf命令行方式,还原度高且稳定 - 若必须用PHPWord,先用
$phpword->getSections()[0]->getElements()手动遍历段落和表格,用MultiCell()或writeHTML()分块构造更可控的HTML - 测试时务必检查生成的中间HTML——用
file_put_contents('debug.html', $html)打开看是否已丢失结构
导出Excel用PhpSpreadsheet比CSV更可靠
CSV看似简单,但遇到逗号、换行、双引号、UTF-8 BOM、Excel自动类型转换(如00123变成123)时极易出错。PhpSpreadsheet生成真正的.xlsx文件,保留格式、公式、多工作表,且兼容性远超自制CSV。
立即学习“PHP免费学习笔记(深入)”;
- 安装:
composer require phpoffice/phpspreadsheet - 写入数字字符串(如工号
00123)必须设单元格类型:$sheet->setCellValueExplicit('A1', '00123', \PhpOffice\PhpSpreadsheet\Cell\DataType::TYPE_STRING) - 大数据量(>5万行)避免一次性
setCellValue(),改用fromArray()批量写入,性能提升3倍以上 - 导出前加BOM头防Excel乱码:
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');+header('Content-Disposition: attachment;filename="data.xlsx"');
生成Word文档别用HTML伪装
用header("Content-Type: application/msword")配合<html xmlns:w="urn:schemas-microsoft-com:office:word">生成的.doc文件,本质是HTML,仅能在旧版Word中勉强打开,新版Office直接报错“文件已损坏”。这不是兼容问题,是格式非法。
- 真正生成.docx必须用
phpoffice/phpword:它基于OOXML标准,输出ZIP包结构,可被所有现代Office识别 - 模板填充推荐
TemplateProcessor类,变量替换安全,支持条件区块和循环表格 - 插入图片需用
addImage()并传入真实路径或资源流,不能只写<img src="xxx"> - 若只需简单文本报告,PDF比Word更可控——用户无法误编辑,样式也不会因Office版本差异而偏移
真正麻烦的从来不是“怎么调用函数”,而是字体路径配错、中间格式失真、内存阈值卡死、以及上线后才发现某台服务器禁用了exec或allow_url_fopen。每个库都有它的边界,越早明确这点,越少半夜改生产配置。



















