You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于PHP与Symfony4按指定关键词解析拆分PDF为多个文件

Symfony 4框架下按关键词拆分PDF的实现方案

你当前使用的smalot/pdfparser仅支持PDF文本解析,不具备PDF结构编辑、拆分能力,搭配纯PHP实现的PDF操作组件即可完成需求,不需要额外安装系统层面的依赖工具。

可选用的开发库

  • smalot/pdfparser:你现有项目已经在用的解析库,保留即可,它支持提取文本内容、文本块坐标、所属页码信息,足够完成关键词定位工作,不需要更换解析方案。
  • setasign/fpdi:PHP生态中稳定性最高的纯PHP PDF页面重组库,支持读取现有PDF、按页抽取内容、拼接生成新的PDF文件,完美兼容Symfony 4,通过Composer可直接安装,部署无额外权限要求。
  • tecnickcom/tcpdf:如果需要做页内内容裁剪(即拆分边界不是整页,而是同一页内的某个区域),可以选用该库配合FPDI使用,实现非整页级别的精细拆分。

不推荐依赖pdftk、Ghostscript等外部命令行工具的方案,这类方案在容器、虚拟主机环境部署时需要额外配置执行权限,适配成本高。

具体实现逻辑

你现有代码仅提取了整页文本,没有记录关键词对应的页码位置,按以下步骤调整即可完成拆分:

  1. 逐页遍历PDF内容时,先匹配起始关键词(如示例中的hello),记录第一次匹配到关键词的页码作为拆分起始点
  2. 从起始点之后继续遍历,匹配结束关键词(如示例中的world),记录匹配到关键词的页码作为拆分结束点
  3. 调用FPDI加载原PDF文件,抽取起始点到结束点之间的所有页面,拼接生成独立的新PDF文件保存即可
  4. 如果需要更精细的区域拆分,不要直接调用getText()取整页内容,改用$page->getDataTm()方法获取每个文本块的坐标、所属位置,定位到关键词的具体页内坐标后,通过FPDI的裁剪功能只保留指定区域内容。

代码改造示例

首先安装需要的依赖库:

composer require smalot/pdfparser setasign/fpdi

对应你原有extract方法的改造代码如下:

public function extract(): Response
{
    // 原PDF文件路径
    $sourcePath = 'C:\Users\lenovo\Desktop\papiers\CV\CVmolkahchaichi.pdf';
    // 拆分后新PDF的保存路径
    $outputPath = 'C:\Users\lenovo\Desktop\papiers\CV\keyword_extracted.pdf';
    $startKeyword = 'hello';
    $endKeyword = 'world';

    // 第一步:定位关键词对应的页码范围
    $parser = new \Smalot\PdfParser\Parser();
    $sourcePdf = $parser->parseFile($sourcePath);
    $pages = $sourcePdf->getPages();
    $startPage = null;
    $endPage = null;

    foreach ($pages as $index => $page) {
        // Smalot页码从0计数,FPDI页码从1计数,后续计算需要+1
        $pageContent = $page->getText();
        // 未记录起始页时,匹配起始关键词
        if ($startPage === null && str_contains($pageContent, $startKeyword)) {
            $startPage = $index + 1;
        }
        // 已经找到起始页后,匹配结束关键词
        if ($startPage !== null && str_contains($pageContent, $endKeyword)) {
            $endPage = $index + 1;
            break;
        }
    }

    // 兜底逻辑:如果没找到结束关键词,默认截取到PDF最后一页
    if ($endPage === null) {
        $endPage = count($pages);
    }

    // 第二步:抽取指定范围页面生成新PDF
    $fpdi = new \setasign\Fpdi\Fpdi();
    $totalPages = $fpdi->setSourceFile($sourcePath);
    // 逐页导入指定范围的内容
    for ($pageNum = $startPage; $pageNum <= $endPage; $pageNum++) {
        $template = $fpdi->importPage($pageNum);
        $pageSize = $fpdi->getTemplateSize($template);
        $fpdi->AddPage($pageSize['orientation'], [$pageSize['width'], $pageSize['height']]);
        $fpdi->useTemplate($template);
    }
    // 保存生成的新PDF
    $fpdi->Output($outputPath, 'F');

    return new Response('指定段落提取完成,文件保存路径:' . $outputPath);
}

如果需要匹配跨页的关键词、或者需要过滤掉页面内关键词之外的无关内容,把整页文本匹配的逻辑替换为逐文本块遍历、记录坐标的逻辑即可,不需要更换核心库。


内容的提问来源于stack exchange,提问作者molyyy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.10 16:15:46