首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >一个快速、实用、开源的 PHP 文档解析器

一个快速、实用、开源的 PHP 文档解析器

作者头像
Tinywan
发布2026-07-01 17:43:13
发布2026-07-01 17:43:13
770
举报
文章被收录于专栏:开源技术小栈开源技术小栈

简介

Parsel 为 PHP 提供了一个 API,用于解析 PDF、Office 文档和图片。您的文档在本地处理,无需将文件发送到外部服务,即可提取纯文本、结构化页面数据、坐标以及截图。

Parsel 可以返回纯文本、结构化文档数据、页面截图,或者针对大型文档逐页返回。它设计为在 PHP 应用程序中使用起来自然流畅,同时在需要时仍能提供高级解析器选项。

示例代码

代码语言:javascript
复制
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:

代码语言:javascript
复制
composer require shipfastlabs/parsel

安装所需的 lit 二进制文件:

代码语言:javascript
复制
vendor/bin/parsel-install-lit

对于 Office 文档、电子表格、演示文稿和图片,您还可以安装系统依赖:

代码语言:javascript
复制
vendor/bin/parsel-install-lit --with-system-dependencies

您可以选择用于安装 lit 二进制文件的包管理器:

代码语言:javascript
复制
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(以下任一命令):

代码语言:javascript
复制
cargo install liteparse
pip install liteparse
npm i -g @llamaindex/liteparse
pnpm add -g @llamaindex/liteparse
bun add -g @llamaindex/liteparse

如果您想自行安装系统依赖,请根据您的平台使用对应命令:

macOS

代码语言:javascript
复制
brew install --cask libreoffice    # 用于 Office 文档
brew install imagemagick           # 用于图片

Ubuntu / Debian

代码语言:javascript
复制
apt-get install libreoffice        # 用于 Office 文档
apt-get install imagemagick        # 用于图片

Windows

代码语言:javascript
复制
choco install libreoffice-fresh    # 用于 Office 文档
choco install imagemagick.app      # 用于图片

说明:LibreOffice 用于 Office 文档转换,ImageMagick 用于图片转换,OCR 支持通过 liteparse 使用 Tesseract。

解析文件

file 方法为磁盘上已存在的文档创建一个解析器实例。选择源文件后,您可以决定以何种方式返回解析结果。

代码语言:javascript
复制
use Shipfastlabs\Parsel;

$text = Parsel::file('/path/to/report.pdf')->text();

您也可以解析原始字节。这在处理上传文件、数据库 Blob 或未保存到磁盘的文档时非常有用。由于字节源不包含文件名,您需要提供文件扩展名。

代码语言:javascript
复制
$document = Parsel::bytes($uploadedBytes, 'pdf')->parse();

Parsel 支持 PDF、Word 文档、电子表格、演示文稿和图片。每种支持的文件类型都使用相同的流畅 API:

代码语言:javascript
复制
$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 在返回前会移除文本输出中的页眉标记。

代码语言:javascript
复制
$text = Parsel::file('document.pdf')
    ->withoutOcr()
    ->text();

结构化文档

parse 方法返回一个 Document 对象,包含文档文本、元数据、页面以及带位置信息的文本项。当您需要坐标、字体信息或 OCR 置信度时非常有用。

代码语言:javascript
复制
$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;
    }
}

文档也可以作为数组返回:

代码语言:javascript
复制
$array = Parsel::file('document.pdf')->toArray();

页面选择

pagepagespageRange 方法可用于限制仅解析特定页面。这些方法是累加的,您可以在解析文档前多次调用它们。

代码语言:javascript
复制
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 方法:

代码语言:javascript
复制
Parsel::file('document.pdf')->maxPages(50)->text();

OCR

默认情况下 OCR 被禁用,以保持解析速度快且可预测。您可以使用 withOcr 方法启用 OCR:

代码语言:javascript
复制
$text = Parsel::file('scan.pdf')->withOcr()->text();

withOcr 方法接受命名参数来设置常用 OCR 选项:

代码语言:javascript
复制
$text = Parsel::file('scan.pdf')
    ->withOcr(
        language: 'fra',
        tessdataPath: '/usr/share/tessdata',
        serverUrl: 'http://localhost:8828/ocr',
        workers: 8,
    )
    ->text();

如果您想明确禁用 OCR,可以调用 withoutOcr

代码语言:javascript
复制
$text = Parsel::file('document.pdf')->withoutOcr()->text();

渲染选项

Parsel 提供了便捷方法来设置常用解析器选项,例如渲染 DPI、保留小文本、加密文档以及每次调用的进程设置。

代码语言:javascript
复制
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 方法直接传递。布尔选项无需值,需要值的选项可作为第二个参数传入。

代码语言:javascript
复制
Parsel::file('document.pdf')->option('some-new-flag');

Parsel::file('document.pdf')->option('some-new-flag', 42);

保存输出

save 方法将解析结果写入磁盘并返回写入的路径。如果目标路径以 .json 结尾,Parsel 将写入 JSON;其他扩展名则写入纯文本。

代码语言:javascript
复制
Parsel::file('document.pdf')->save('document.txt');

Parsel::file('document.pdf')->save('document.json');

截图

您可以使用 screenshots 方法将页面截图渲染到指定目录。该方法在解析完成后返回输出目录中的图像文件。

代码语言:javascript
复制
$screenshots = Parsel::file('document.pdf')
    ->pageRange(1, 5)
    ->screenshots('/tmp/parsel-pages');

为获得可预测的结果,应传入一个专用的、不包含无关文件的输出目录。

流式处理大型文档

parsetoArray 方法会将整个文档加载到内存中。对于大型文档,您可以使用 lazyPages 逐页处理。

代码语言:javascript
复制
foreach (Parsel::file('large-document.pdf')->lazyPages() as $page) {
    foreach ($page->items as $item) {
        // 逐页处理...
    }
}

这允许 Parsel 增量读取页面,而无需将整个文档保存在内存中。

文档数据结构

解析后的 Document 包含完整文本、元数据和页面列表。每页包含尺寸、页面文本以及带位置数据的文本项。

代码语言:javascript
复制
$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 二进制文件:

  1. 通过 withBinary 配置的单次调用二进制文件。
  2. 通过 Parsel::usingBinary 配置的全局二进制文件。
  3. PARSEL_LIT_BINARY 环境变量。
  4. 系统 PATH 中的 lit 二进制文件。

如果无法找到二进制文件,Parsel 将抛出 BinaryNotFoundException

代码语言:javascript
复制
Parsel::usingBinary('/usr/local/bin/lit');

Parsel::defaultTimeout(120);

测试

Parsel 包含一个模拟运行器,允许您的测试在不启动真实二进制文件的情况下测试解析代码。响应键作为子字符串与命令行匹配。当多个响应匹配时,使用最长的匹配键。

代码语言:javascript
复制
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 来保持代码格式化和充分测试。

代码语言:javascript
复制
composer lint
composer test:types
composer test:unit
composer test

集成测试针对真实解析器安装运行,当 lit 二进制文件不可用时会跳过:

代码语言:javascript
复制
./vendor/bin/pest --group=integration
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2026-06-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 开源技术小栈 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 简介
  • 安装
  • 解析文件
  • 纯文本输出
  • 结构化文档
  • 页面选择
  • OCR
  • 渲染选项
  • 附加选项
  • 保存输出
  • 截图
  • 流式处理大型文档
  • 文档数据结构
  • 二进制文件解析顺序
  • 测试
  • 开发
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档