yii本身不直接解析pdf,所谓“yii解析pdf乱码”实为第三方库(如pdfplumber、tcpdf、pdfminer)在处理中文时因字体未嵌入、编码异常或pdf类型误判所致;须先区分文字型(可选中复制)与扫描图像型(需ocr),再针对性配置字体回退、启用ocr或修复编码链路。

Yii本身不直接解析PDF,所谓“Yii解析PDF乱码”,实际是项目中用了第三方PDF处理库(如tcpdf、mpdf、pdfminer封装、或调用pdftotext/pdfplumber等),在提取中文时因字体、编码或结构问题导致乱码。解决核心不是改Yii代码,而是找准解析层的瓶颈并针对性干预。
确认PDF类型:文字型 or 扫描图像型
这是所有操作的前提——跳过这步,后续全是白忙。
- 用鼠标尝试选中任意一段中文:能高亮+复制出正常汉字 → 属于文字型PDF(含嵌入字体或Unicode映射)
- 无法选中,或复制出来是空格/方块/乱码符号 → 是扫描图像型PDF,必须走OCR路径
文字型PDF乱码:重点查字体与CMAP
这类PDF有文本流,但解析器找不到中文字体映射关系,常见于导出自WPS、老旧LaTeX或网页转PDF的文件。
- 用Adobe Acrobat打开 → 文件 → 属性 → 字体标签页,看是否列出
SimSun、Noto Sans CJK SC、Source Han Serif等中文字体;若显示“未嵌入”或只有ABCDEE+xxx类乱码字体名,说明字体缺失 - 在Yii中调用
pdfplumber时,加参数强制指定字体回退:page.extract_text(x_tolerance=1, y_tolerance=1, layout=True, codec='utf-8'),同时确保系统已安装对应TrueType字体(如fonts-wqy-zenhei在Linux) - 若用
pdfminer.high_level.extract_text(),需手动加载CMAP支持:设置laparams=LAParams(char_margin=2.0, line_margin=0.5, word_margin=0.1),并确认pdfminer版本≥20230000(旧版对CID字体支持弱)
扫描图像型PDF:必须启用OCR
纯图像PDF没有可读文本流,任何基于PDF结构的解析都会失败,OCR是唯一可靠路径。
- 在Yii控制器中调用外部OCR工具最稳妥:用
exec()或proc_open()运行tesseract命令,例如:tesseract input.pdf stdout -l chi_sim+eng --psm 6(注意提前将PDF转为300dpi PNG) - 避免在Web请求中长时间阻塞:建议把OCR任务推入队列(如Yii2的
yii\queue),异步处理并回调结果 - 若部署环境受限(如无tesseract),可用轻量级替代方案:调用
pdftotext -layout -enc UTF-8 file.pdf -,虽对扫描件无效,但对部分“伪扫描”(即带隐藏文本层的PDF)有时能意外奏效
统一输出与存储环节防二次乱码
即使提取成功,保存到数据库或返回JSON时仍可能因编码不一致变乱码。
- Yii应用配置中确保
'charset' => 'UTF-8',数据库连接DSN包含;charset=utf8mb4 - 返回JSON前用
json_encode($data, JSON_UNESCAPED_UNICODE),避免中文被转成\uXXXX - 调试时用
bin2hex($text)检查提取结果原始字节:若开头是efbbbf(BOM),或大量3f(问号),说明上游已损坏,需回溯解析步骤











