一文搞懂PHP生成PDF文档

夏辰君_2890

夏辰君_2890

2026-05-19

833人浏览

原创

php生成pdf需依赖tcpdf、mpdf、dompdf等外部库;tcpdf需显式加载中文字体并避免writehtml;mpdf仅支持部分css2.1属性;dompdf处理大表格易内存溢出;导出时须严格控制http头与输出缓冲。

一文搞懂php生成pdf文档

PHP 本身不内置 PDF 生产能力,直接用 echo 输出 PDF 二进制或靠浏览器渲染 HTML 为 PDF 都不可靠——真要稳定生成 PDF,得依赖外部库,而 tcpdf、mpdf、dompdf 是目前最常被选中的三个,它们定位和适用场景差异明显,选错就容易卡在中文乱码、分页错位、CSS 不生效这些地方。

为什么 tcpdf 生成中文经常是方块或空白

tcpdf 默认字体不支持 UTF-8 中文,即使你用了 setLanguageArray() 或设置了 mb_internal_encoding('UTF-8'),只要没显式加载中文字体,文本照样渲染失败。

  • 必须用 addTTFfont() 提前注册一个支持中文的 TrueType 字体(如 simhei.ttf 或 msyh.ttc),再通过 setFont() 切换过去
  • 字体文件路径需为服务器绝对路径,相对路径在 CLI 模式下大概率失效
  • 别用 writeHTML() 直接塞含中文的 HTML —— 它对内联样式和自定义字体的支持弱,优先改用 Cell()、MultiCell() 等原生方法写入文本
  • 若坚持用 HTML 渲染,得配合 setHtmlVSpace() 和 setRTL() 调整行高与方向,否则中文段落会挤在一起

mpdf 里 CSS margin/padding 不生效的常见原因

mpdf 对 CSS 的支持比 tcpdf 强,但不是全兼容。比如 margin-top: auto、display: grid、position: sticky 这些现代属性它压根不认。

btpanel phpsite 宝塔面板PHP网站
btpanel phpsite 宝塔面板PHP网站

宝塔面板 PHP 网站管理:站点创建、删除、启停、PHP 版本切换、域名管理、SSL证书管理、伪静态管理、数据库管理

下载
  • 只认部分 CSS2.1 属性,flex 布局基本无效,表格布局更稳
  • @media print 规则会被忽略,响应式写法在这里没意义
  • 外边距折叠(margin collapse)行为和浏览器不一致,建议统一用 padding 控制内部间距,margin 只用于模块间隔离
  • 如果用了 autoScriptToLang 或 useSubstitutions,某些字体替换逻辑会干扰盒模型计算,关掉试试

dompdf 渲染大表格时内存溢出或超时

dompdf 是纯 PHP 实现,解析 HTML + CSS + 渲染三步都在内存里完成,遇到几百行带样式表格很容易撑爆 memory_limit 或触发 max_execution_time。

  • 把大表格拆成多个 <table>,每 30–50 行一组,中间用空 <code><div style="page-break-inside: avoid"></div> 隔开
  • 禁用 DOMPDF_ENABLE_CSS_FLOAT(默认开启),浮动元素是性能黑洞
  • 避免在 <td> 里嵌套多层 <code><div>,用 <code>border-collapse: collapse 替代边框模拟
  • 生成前调用 ini_set('memory_limit', '512M') 和 set_time_limit(300),但治标不治本,关键还是精简 HTML 结构
  • 导出 PDF 时浏览器下载失败或文件损坏

    不是库的问题,90% 出在 HTTP 响应头或输出缓冲控制不当。

    • 必须在 Output() 或 stream() 前清空所有输出缓冲:ob_end_clean(),不能只靠 ob_flush()
    • 响应头顺序很重要:先 Content-Type: application/pdf,再 Content-Disposition: attachment; filename="xxx.pdf",最后才是 Content-Length
    • 如果用了框架(如 Laravel、ThinkPHP),确保没在 PDF 生成前触发日志写入、调试信息输出或自动 JSON 化响应
    • 开发时用 file_put_contents('debug.pdf', $pdf->Output('S')) 先保存到磁盘验证内容是否正常,再排查传输链路

    PDF 生成从来不是“调个函数就完事”的事——字体、CSS、内存、HTTP 头,每个环节都可能静默失败。最稳妥的做法,是先用最小 HTML + 最简样式跑通流程,再逐项加功能,而不是一上来就塞满业务数据和复杂样式。

php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!

相关文章

极轻PDF
极轻PDF

专业的在线PDF工具,支持PDF编辑、转换、合并、压缩等多种功能,操作简单,处理高效,满足日常办公与学习中的PDF处理需求。

下载

相关标签:

php

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
php文件怎么打开
php文件怎么打开

打开php文件步骤:1、选择文本编辑器;2、在选择的文本编辑器中,创建一个新的文件,并将其保存为.php文件;3、在创建的PHP文件中,编写PHP代码;4、要在本地计算机上运行PHP文件,需要设置一个服务器环境;5、安装服务器环境后,需要将PHP文件放入服务器目录中;6、一旦将PHP文件放入服务器目录中,就可以通过浏览器来运行它。

2023.09.01

9944

6

php怎么取出数组的前几个元素
php怎么取出数组的前几个元素

取出php数组的前几个元素的方法有使用array_slice()函数、使用array_splice()函数、使用循环遍历、使用array_slice()函数和array_values()函数等。本专题为大家提供php数组相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.11

5921

5

php反序列化失败怎么办
php反序列化失败怎么办

php反序列化失败的解决办法检查序列化数据。检查类定义、检查错误日志、更新PHP版本和应用安全措施等。本专题为大家提供php反序列化相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.11

2075

5

php怎么连接mssql数据库
php怎么连接mssql数据库

连接方法:1、通过mssql_系列函数;2、通过sqlsrv_系列函数;3、通过odbc方式连接;4、通过PDO方式;5、通过COM方式连接。想了解php怎么连接mssql数据库的详细内容,可以访问下面的文章。

2023.10.23

3708

4

php连接mssql数据库的方法
php连接mssql数据库的方法

php连接mssql数据库的方法有使用PHP的MSSQL扩展、使用PDO等。想了解更多php连接mssql数据库相关内容,可以阅读本专题下面的文章。

2023.10.23

4394

6

html怎么上传
html怎么上传

html通过使用HTML表单、JavaScript和PHP上传。更多关于html的问题详细请看本专题下面的文章。php中文网欢迎大家前来学习。

2023.11.03

3451

9

PHP出现乱码怎么解决
PHP出现乱码怎么解决

PHP出现乱码可以通过修改PHP文件头部的字符编码设置、检查PHP文件的编码格式、检查数据库连接设置和检查HTML页面的字符编码设置来解决。更多关于php乱码的问题详情请看本专题下面的文章。php中文网欢迎大家前来学习。

2023.11.09

4917

8

php文件怎么在手机上打开
php文件怎么在手机上打开

php文件在手机上打开需要在手机上搭建一个能够运行php的服务器环境,并将php文件上传到服务器上。再在手机上的浏览器中输入服务器的IP地址或域名,加上php文件的路径,即可打开php文件并查看其内容。更多关于php相关问题,详情请看本专题下面的文章。php中文网欢迎大家前来学习。

2023.11.13

3842

8

sprintf函数用法详解
sprintf函数用法详解

sprintf函数的用法:1、格式化字符串;2、指定输出宽度和精度;3、返回值。更多关于sprintf函数用法详解的内容,大家可以阅读下面的文章。

2023.11.27

11822

4

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
墨刀帮助中心
墨刀帮助中心

共0课时 | 0人学习

MyEclipse学习中心
MyEclipse学习中心

共0课时 | 0人学习

Apache Subversion 官方手册
Apache Subversion 官方手册

共0课时 | 0人学习