Yii框架不直接解析PDF,乱码源于底层解析库编码处理失效;读取时需检查字体嵌入与ToUnicode表,生成时须正确加载中文字体并设UTF-8编码。

Yii 框架本身不直接解析 PDF 内容,读取 PDF 文本乱码问题,本质是底层 PDF 解析库(如 tcpdf、fpdi、smalot/pdfparser 或系统命令行工具)在处理编码、字体映射或 ToUnicode 表时失效所致。乱码通常表现为中文显示为方块、问号、空格,或复制文本出现错位/缺失——这不是 Yii 的 bug,而是 PDF 文件结构与解析方式不匹配的结果。
确认乱码来源:先分清是“读取”还是“生成”环节
Yii 中涉及 PDF 的常见场景有两种,处理逻辑完全不同:
-
读取已有 PDF(如提取文字、校验内容):依赖第三方解析器(如
smalot/pdfparser),乱码多因字体未嵌入、ToUnicode 缺失、或解析器不支持 CID 字体; -
用 Yii 输出 PDF(如导出报表):使用
tcpdf或mpdf等扩展,乱码主因是未正确加载中文字体或未设置 UTF-8 编码。
请先明确你是在 file_get_contents() 后用正则提取?还是调用 PDFParser::parseContent()?或是用 tcpdf->writeHTML() 生成?不同路径,解法差异很大。
读取 PDF 时中文乱码的实用修复方案
若你用的是 smalot/pdfparser(Yii 常见选择),它默认不执行 OCR,仅解析文本流。当 PDF 是扫描件或字体未嵌入时,getText() 返回空或乱码属正常现象。
- 检查 PDF 是否含真实文本:用 Adobe Acrobat →「文件」→「属性」→「字体」,看是否有「未嵌入」或「CIDFont」字样;
- 强制启用字符映射回退:在解析前设置
$parser->setOptions(['ignore_invalid_encoding' => true]); - 对 GBK 编码 PDF,手动转码:获取原始字符串后,用
iconv('gbk', 'utf-8//IGNORE', $rawText)尝试转换; - 终极手段:调用系统级 OCR 工具(如
tesseract)处理 PDF 页面图像——需先用Imagick或ghostscript将 PDF 转为 PNG,再 OCR 识别。
Yii 中生成 PDF 时避免中文乱码的关键配置
如果你用 tcpdf 扩展(如 yii2-tcpdf),以下三步缺一不可:
- 下载并注册中文字体:将
simhei.ttf放入@vendor/tecnickcom/tcpdf/fonts/,运行tcpdf/tools/tcpdf_addfont.php生成simhei.php和simhei.z; - 初始化时指定字体:
$pdf = new TCPDF(); $pdf->setLanguageArray(['a_meta_charset' => 'UTF-8']); $pdf->AddFont('simhei', '', 'simhei.php'); $pdf->SetFont('simhei', '', 12);; - 确保 HTML 内容本身是 UTF-8:Yii 视图中不要用 GBK 编码保存 PHP 文件,模板输出前加
header('Content-Type: text/html; charset=utf-8');(虽非必须,但可排除干扰)。
绕过解析,用 sendFile 安全交付 PDF 文件
如果目标只是让用户下载或预览 PDF(而非提取内容),根本无需解析——直接用 Yii 原生 sendFile():
- 它不触碰文件内容,只设置标准 HTTP 头(
Content-Type: application/pdf、Content-Disposition: inline); - 浏览器收到后交由自身 PDF 渲染引擎处理,是否乱码取决于用户端阅读器和系统字体,与 Yii 无关;
- 代码示例:
return Yii::$app->response->sendFile($filePath, $fileName, ['inline' => true]);。



















