codeigniter自身无法生成pdf,必须集成dompdf、mpdf或tcpdf等第三方库;其中mpdf对中文和css支持最佳但内存占用高,dompdf部署轻量但css兼容性差,tcpdf功能全但api繁琐易出错。

直接用 CodeIgniter 自身无法生成 PDF,必须集成第三方库。最常用且稳定的是 dompdf、mpdf 和 TCPDF,但三者行为差异大,选错容易卡在中文乱码、分页失败、CSS 不生效或下载空白这几个坑里。
dompdf 适合简单 HTML 转 PDF,但别指望它渲染复杂 CSS
dompdf 是纯 PHP 实现,无需扩展,部署最轻量,但对 Flex/Grid/Float 支持极弱,@media print 基本无效。常见错误是页面内容被截断或样式全丢。
- 必须用内联
style或<style></style>标签写样式,外部 CSS 文件需用file_get_contents()读入后传给load_html() - 中文需显式设置字体:在 HTML 中加
<style>body{font-family: "simhei", sans-serif;}</style>,并确保服务器有对应字体文件(如simhei.ttf)且已注册进dompdf配置 - 调用
$dompdf->stream("report.pdf")会直接输出到浏览器;若要强制下载,改用$dompdf->download("report.pdf")(CI4+ dompdf v2.0+ 才支持,旧版需手动设 header)
mpdf 对中文和 CSS 支持最好,但内存占用高
mpdf 是目前 CI 项目中处理中文 PDF 最稳的选择,能较好解析 float、page-break-inside: avoid,也支持 UTF-8 字体嵌入。但生成千行以上表格时容易触发 Allowed memory size exhausted 错误。
- 初始化必须指定字体:例如
$mpdf = new \Mpdf\Mpdf(['mode' => 'utf-8', 'format' => 'A4', 'margin_left' => 10, 'margin_right' => 10]); - 不要用
WriteHTML($html, 2)两次(一次样式一次内容),会导致样式丢失;应把 CSS 内容合并进 HTML 字符串再一次性写入 - 批量生成多个 PDF 时,每次循环后必须调用
$mpdf->clean()或重建实例,否则后续 PDF 会叠加前一次内容
TCPDF 适合高度定制化场景,但 API 繁琐易出错
TCPDF 功能最全(支持条形码、数字签名、多栏排版),但不接受任意 HTML,对标签语义要求严格。常见错误是 writeHTMLCell() 输出为空、addPage() 后内容错位、或 Output() 报 headers already sent。
- 避免在
Output()前有任何echo、print_r、空格或 BOM 字符,CI 的output类可能已开启缓冲,建议在控制器开头加ob_end_clean(); -
writeHTMLCell()第一个参数为宽度(0表示自动),但若父容器无明确宽度,内容可能塌陷;推荐先用setCellPadding()和setCellHeightRatio()微调 - 中文需加载字体:用
addTTFfont()注册simhei.ttf,再通过setFont()切换,不能只靠setLanguageArray()
下载 PDF 时空白或 ERR_INVALID_RESPONSE 的真实原因
这不是 PDF 库的问题,而是 CI 的输出控制与浏览器响应头冲突。典型现象是点击下载链接后页面变白、弹窗没反应、Chrome 显示 ERR_INVALID_RESPONSE。
- 确保控制器方法末尾**没有额外 echo / var_dump / 空行**,尤其注意视图文件末尾是否有多余换行
- 不要混用
force_download()和库自身的Output(..., 'D');前者用于已生成的文件路径,后者用于内存中流式输出 —— 二者只能选其一 - CI4 中若启用了
Cache-Control: no-cache全局策略,PDF 下载会被拦截;可在输出前加$this->response->setHeader('Cache-Control', 'private');
真正麻烦的不是“怎么生成”,而是“生成后怎么不出错”。字体路径错一位、header 多发一次、内存没清理、甚至模板里一个未闭合的 <div>,都可能导致 PDF 渲染中断或下载失败。调试时优先检查网络面板的响应体是否为二进制数据,而不是 HTML 错误页。</div>











