yii读取pdf中文乱码主因是编码不匹配,解决关键为提取字节流、映射字体、转utf-8;推荐用pdftotext预处理或fpdi+tcpdf/mpdf配合中文字体。

Yii框架中读取PDF中文内容出现乱码,核心原因是PDF文本编码与PHP解析时的字符集不匹配,尤其当PDF使用自定义字体或内嵌CJK(中日韩)字体时,原始文本流未按UTF-8处理。解决关键在于:正确提取原始字节流 + 映射字体编码 + 转换为UTF-8。以下为可落地的解决实例。
使用TCPDF或FPDI配合Unicode字体解析PDF
原生PHP的pdf_parser扩展或简单正则提取无法处理中文PDF的字体映射逻辑。推荐用支持Unicode的库:
- 使用FPDI + TCPDF加载PDF并读取页面内容(需提前知道文字位置或通过第三方OCR辅助)
- TCPDF内置
addTTFfont()方法可注册中文字体(如simhei.ttf),确保导出/渲染时无乱码 - 若仅需提取文本,优先考虑xpdf工具链(如
pdftotext)并指定编码:pdftotext -enc UTF-8 input.pdf -
用poppler-utils的pdftotext命令行预处理(最稳定)
在Yii控制器中调用系统命令,绕过PHP解析局限:
- 确认服务器已安装poppler-utils:
sudo apt-get install poppler-utils(Ubuntu) - 在Yii中执行:
$text = shell_exec('pdftotext -enc UTF-8 "' . escapeshellarg($pdfPath) . '" - 2>/dev/null'); - 对结果做基础清洗:
trim(preg_replace('/\s+/', ' ', $text)),去除多余空白 - 注意:确保PDF本身含可复制文本(非扫描图),否则返回为空
处理内嵌字体导致的编码偏移(进阶)
部分PDF将中文映射到私有编码区间(如Adobe-GB1-5),需手动建立CID→Unicode映射:
- 用
pdfinfo -meta和pdfdump(来自xpdf)分析字体编码方式 - 借助开源映射表(如GitHub上
pdf-cid2unicode项目)将CID转为UTF-8码点 - 在Yii中封装转换逻辑,例如:
$utf8Str = iconv('UCS-2BE', 'UTF-8', pack('n*', ...$cidArray));(需按PDF中ToUnicode CMap解析)
Yii响应输出PDF中文内容时的编码设置
若将提取后的中文内容以PDF形式重新输出,必须显式声明字体:
- 使用mPDF替代TCPDF(对中文更友好):
composer require mpdf/mpdf - 初始化时指定中文字体:
$mpdf = new \Mpdf\Mpdf(['autoScriptToLang' => true, 'autoLangToFont' => true]);<br> $mpdf->WriteHTML($chineseText);
- 避免直接echo中文PDF二进制流,而应设置Header:
header('Content-Type: application/pdf');<br> header('Content-Disposition: inline; filename="content.pdf"');











