yii需借助第三方库解析pdf文字,推荐smalot/pdfparser(轻量、纯php、中文支持好),但仅适用于文本型pdf;扫描件需ocr预处理,加密pdf需外部解密,乱码常因字体映射或文字转路径所致,可辅以pdftotext提升准确率。

Yii本身不提供PDF文字解析能力,需借助第三方PHP库(如smalot/pdfparser或setasign/fpdi搭配tcpdf)完成PDF文本提取。Yii2项目中推荐使用smalot/pdfparser,它轻量、纯PHP实现、无需扩展依赖,且对中文PDF支持较好(前提是PDF内文字为可选中状态,非扫描图)。
安装 smalot/pdfparser 扩展
在项目根目录执行:
composer require smalot/pdfparser- 确保PDF文件是文本型(非OCR扫描件),否则将返回空内容
Controller中读取PDF文字的示例代码
在任意控制器方法中(如SiteController::actionReadPdf()):
use Smalot\PdfParser\Parser;
<p>// 假设PDF路径为 @app/uploads/sample.pdf
$pdfPath = Yii::getAlias('@app/uploads/sample.pdf');</p><p>if (!file_exists($pdfPath)) {
throw new \yii\web\HttpException(404, 'PDF文件不存在');
}</p><p>$parser = new Parser();
$pdf = $parser->parseFile($pdfPath);</p><p>// 获取全部文本(自动合并所有页)
$text = $pdf->getText();</p><p>// 或逐页获取
$pages = $pdf->getPages();
foreach ($pages as $i => $page) {
echo "第" . ($i + 1) . "页:\n" . $page->getText() . "\n\n";
}
</p>
注意:$pdf->getText()返回的是纯字符串,含换行与空格,不含格式信息;若PDF含加密或权限限制,需先解密(该库不支持解密,需用qpdf等命令行工具预处理)。
处理中文乱码或提取为空的常见原因
不是编码问题,而是PDF内部结构导致:
- 扫描件PDF:本质是图片,无文字对象 → 必须先OCR(如调用Umi-OCR或PaddleOCR API)
-
嵌入字体未映射Unicode:尤其老版PDF用自定义编码 → 可尝试启用
force_encoding参数(需修改源码或升级到v2.x分支) -
文字被渲染为路径(glyphs):某些生成工具(如某些LaTeX导出)会将文字转为矢量路径 →
pdfparser无法识别,需换用poppler-utils中的pdftotext命令行工具
补充:用系统命令 pdftotext 辅助提取(更稳定)
若服务器可执行命令,pdftotext(来自poppler)准确率远高于纯PHP方案:
- Ubuntu/Debian安装:
sudo apt install poppler-utils - Yii中调用:
$text = shell_exec("pdftotext -enc UTF-8 {$pdfPath} - 2>/dev/null"); - 优势:支持CJK字体映射、自动处理编码、能提取受保护PDF(如有密码,加
-password 'xxx')











