Parsel 为 PHP 提供了一个 API,用于解析 PDF、Office 文档和图片。您的文档在本地处理,无需将文件发送到外部服务,即可提取纯文本、结构化页面数据、坐标以及截图。
Parsel 可以返回纯文本、结构化文档数据、页面截图,或者针对大型文档逐页返回。它设计为在 PHP 应用程序中使用起来自然流畅,同时在需要时仍能提供高级解析器选项。
示例代码
use Shipfastlabs\Parsel;
$text = Parsel::file('invoice.pdf')->text();
$document = Parsel::file('invoice.pdf')
->pageRange(1, 5)
->withOcr(language: 'eng')
->withDpi(300)
->parse();
foreach ($document->pages as $page) {
foreach ($page->items as $item) {
echo"{$item->text} @ ({$item->x}, {$item->y})\n";
}
}
Parsel 需要 PHP 8.4 或更高版本 以及 lit 二进制文件。
通过 Composer 安装 Parsel:
composer require shipfastlabs/parsel
安装所需的 lit 二进制文件:
vendor/bin/parsel-install-lit
对于 Office 文档、电子表格、演示文稿和图片,您还可以安装系统依赖:
vendor/bin/parsel-install-lit --with-system-dependencies
您可以选择用于安装 lit 二进制文件的包管理器:
vendor/bin/parsel-install-lit --manager=npm
vendor/bin/parsel-install-lit --manager=pnpm
vendor/bin/parsel-install-lit --manager=bun
vendor/bin/parsel-install-lit --manager=pip
vendor/bin/parsel-install-lit --manager=cargo
您也可以自行安装 lit(以下任一命令):
cargo install liteparse
pip install liteparse
npm i -g @llamaindex/liteparse
pnpm add -g @llamaindex/liteparse
bun add -g @llamaindex/liteparse
如果您想自行安装系统依赖,请根据您的平台使用对应命令:
macOS
brew install --cask libreoffice # 用于 Office 文档
brew install imagemagick # 用于图片
Ubuntu / Debian
apt-get install libreoffice # 用于 Office 文档
apt-get install imagemagick # 用于图片
Windows
choco install libreoffice-fresh # 用于 Office 文档
choco install imagemagick.app # 用于图片
说明:LibreOffice 用于 Office 文档转换,ImageMagick 用于图片转换,OCR 支持通过 liteparse 使用 Tesseract。
file 方法为磁盘上已存在的文档创建一个解析器实例。选择源文件后,您可以决定以何种方式返回解析结果。
use Shipfastlabs\Parsel;
$text = Parsel::file('/path/to/report.pdf')->text();
您也可以解析原始字节。这在处理上传文件、数据库 Blob 或未保存到磁盘的文档时非常有用。由于字节源不包含文件名,您需要提供文件扩展名。
$document = Parsel::bytes($uploadedBytes, 'pdf')->parse();
Parsel 支持 PDF、Word 文档、电子表格、演示文稿和图片。每种支持的文件类型都使用相同的流畅 API:
$text = Parsel::file('contract.docx')->text();
$rows = Parsel::file('report.xlsx')->text();
$slides = Parsel::file('deck.pptx')->text();
$scan = Parsel::file('receipt.png')
->withOcr()
->text();
$photo = Parsel::file('invoice.jpg')
->withOcr(language: 'eng')
->parse();
text 方法以字符串形式返回解析后的文档文本。Parsel 在返回前会移除文本输出中的页眉标记。
$text = Parsel::file('document.pdf')
->withoutOcr()
->text();
parse 方法返回一个 Document 对象,包含文档文本、元数据、页面以及带位置信息的文本项。当您需要坐标、字体信息或 OCR 置信度时非常有用。
$document = Parsel::file('document.pdf')->parse();
echo $document->text;
echo $document->pageCount();
foreach ($document->pages as $page) {
foreach ($page->items as $item) {
echo $item->text;
}
}
文档也可以作为数组返回:
$array = Parsel::file('document.pdf')->toArray();
page、pages 和 pageRange 方法可用于限制仅解析特定页面。这些方法是累加的,您可以在解析文档前多次调用它们。
Parsel::file('document.pdf')->page(7);
Parsel::file('document.pdf')->pages(1, 3, 5);
Parsel::file('document.pdf')->pages('1-5', 10);
Parsel::file('document.pdf')->pageRange(1, 5);
Parsel::file('document.pdf')->pageRange(1, 5)->page(10);
如果只需限制解析的页面数量,可使用 maxPages 方法:
Parsel::file('document.pdf')->maxPages(50)->text();
默认情况下 OCR 被禁用,以保持解析速度快且可预测。您可以使用 withOcr 方法启用 OCR:
$text = Parsel::file('scan.pdf')->withOcr()->text();
withOcr 方法接受命名参数来设置常用 OCR 选项:
$text = Parsel::file('scan.pdf')
->withOcr(
language: 'fra',
tessdataPath: '/usr/share/tessdata',
serverUrl: 'http://localhost:8828/ocr',
workers: 8,
)
->text();
如果您想明确禁用 OCR,可以调用 withoutOcr:
$text = Parsel::file('document.pdf')->withoutOcr()->text();
Parsel 提供了便捷方法来设置常用解析器选项,例如渲染 DPI、保留小文本、加密文档以及每次调用的进程设置。
Parsel::file('document.pdf')->withDpi(300);
Parsel::file('document.pdf')->preserveSmallText();
Parsel::file('secret.pdf')->withPassword('hunter2');
Parsel::file('document.pdf')->withBinary('/usr/local/bin/lit');
Parsel::file('document.pdf')->withTimeout(120);
如果需要传递 Parsel 尚未提供专用方法的标志,可以使用 option 方法直接传递。布尔选项无需值,需要值的选项可作为第二个参数传入。
Parsel::file('document.pdf')->option('some-new-flag');
Parsel::file('document.pdf')->option('some-new-flag', 42);
save 方法将解析结果写入磁盘并返回写入的路径。如果目标路径以 .json 结尾,Parsel 将写入 JSON;其他扩展名则写入纯文本。
Parsel::file('document.pdf')->save('document.txt');
Parsel::file('document.pdf')->save('document.json');
您可以使用 screenshots 方法将页面截图渲染到指定目录。该方法在解析完成后返回输出目录中的图像文件。
$screenshots = Parsel::file('document.pdf')
->pageRange(1, 5)
->screenshots('/tmp/parsel-pages');
为获得可预测的结果,应传入一个专用的、不包含无关文件的输出目录。
parse 和 toArray 方法会将整个文档加载到内存中。对于大型文档,您可以使用 lazyPages 逐页处理。
foreach (Parsel::file('large-document.pdf')->lazyPages() as $page) {
foreach ($page->items as $item) {
// 逐页处理...
}
}
这允许 Parsel 增量读取页面,而无需将整个文档保存在内存中。
解析后的 Document 包含完整文本、元数据和页面列表。每页包含尺寸、页面文本以及带位置数据的文本项。
$document->text;
$document->metadata;
$document->pages;
$document->pageCount();
$page->number;
$page->width;
$page->height;
$page->text;
$page->items;
$item->text;
$item->x;
$item->y;
$item->width;
$item->height;
$item->fontName;
$item->fontSize;
$item->confidence;
Parsel 需要解析文档时,按以下顺序查找 lit 二进制文件:
withBinary 配置的单次调用二进制文件。Parsel::usingBinary 配置的全局二进制文件。PARSEL_LIT_BINARY 环境变量。lit 二进制文件。如果无法找到二进制文件,Parsel 将抛出 BinaryNotFoundException。
Parsel::usingBinary('/usr/local/bin/lit');
Parsel::defaultTimeout(120);
Parsel 包含一个模拟运行器,允许您的测试在不启动真实二进制文件的情况下测试解析代码。响应键作为子字符串与命令行匹配。当多个响应匹配时,使用最长的匹配键。
use Shipfastlabs\Parsel;
$fake = Parsel::fake([
'--format json' => file_get_contents(__DIR__.'/fixtures/lit-output.json'),
]);
$document = Parsel::file('invoice.pdf')->parse();
expect($fake->recordedCommands()[0])->toContain('--format', 'json');
字符串响应作为成功的 stdout 返回。如果需要控制退出码或 stderr,可以提供 ProcessResult 实例。
Parsel 使用 Pint、Rector、PHPStan 和 Pest 来保持代码格式化和充分测试。
composer lint
composer test:types
composer test:unit
composer test
集成测试针对真实解析器安装运行,当 lit 二进制文件不可用时会跳过:
./vendor/bin/pest --group=integration