【问题标题】:Count the number of pages in a PDF in only PHP [closed]仅在 PHP 中计算 PDF 中的页数 [关闭]
【发布时间】:2010-11-11 17:53:17
【问题描述】:

我需要一种方法来计算 PHP 中 PDF 的页数。我做了一些谷歌搜索,我发现的唯一东西要么使用 shell/bash 脚本、perl 或其他语言,但我需要原生 PHP 中的一些东西。是否有任何库或示例说明如何执行此操作?

【问题讨论】:

标签: php pdf


【解决方案1】:

如果使用 Linux,这比使用identify 获取页数要快得多(尤其是在页数较多的情况下):

exec('/usr/bin/pdfinfo '.$tmpfname.' | awk \'/Pages/ {print $2}\'', $output);

您确实需要安装 pdfinfo。

【讨论】:

  • 哇,这比这里列出的任何其他方法快 1000000 倍。干杯。
  • +1 使用正确的方法!
  • 您可能需要使用which phpinfo 来获取绝对路径。还要在服务器上安装phpinfo
  • qpdf 也是一个选项。一个优点是您不必解析输出。 qpdf --show-npages file.pdf 仅返回带有换行符的 页数。所以你只需要trim()/parseInt()trim(shell_exec('qpdf --show-npages ' . escapeshellarg($file)))
【解决方案2】:

我知道这已经很老了......但如果它现在与我相关,它也可能与其他人相关。

我刚刚制定了这种获取页码的方法,因为这里列出的方法效率低下,而且对于大型 PDF 来说非常慢。

$im = new Imagick();
$im->pingImage('name_of_pdf_file.pdf');
echo $im->getNumberImages();

似乎对我很有效!

【讨论】:

    【解决方案3】:

    您可以使用 PHP 的 ImageMagick 扩展。 ImageMagick 理解 PDF,您可以使用 identify 命令提取页数。 PHP函数是Imagick::identifyImage()

    【讨论】:

    • 这是一个相当古老的答案。您可能想看看TCPDI。这完全一样,无需添加额外的 PHP 库 $pageCount = (new TCPDI())->setSourceData((string)file_get_contents($fileName));
    • TCPDI 也是一个库。
    • 我使用正则表达式 preg_match('/\/Count\s?(?<value>\d+)\s?\/Type\s*?\/Pages/', $chunk, $matches) 来计算 Pdf v1.7 的页数,这里是完整的解决方案 rcadhikari.blogspot.com/2021/03/…
    【解决方案4】:

    我实际上采用了一种组合方法。由于我在服务器上禁用了 exec,我想坚持使用基于 PHP 的解决方案,所以最终得到了这个:

    代码:

    function getNumPagesPdf($filepath){
        $fp = @fopen(preg_replace("/\[(.*?)\]/i", "",$filepath),"r");
        $max=0;
        while(!feof($fp)) {
                $line = fgets($fp,255);
                if (preg_match('/\/Count [0-9]+/', $line, $matches)){
                        preg_match('/[0-9]+/',$matches[0], $matches2);
                        if ($max<$matches2[0]) $max=$matches2[0];
                }
        }
        fclose($fp);
        if($max==0){
            $im = new imagick($filepath);
            $max=$im->getNumberImages();
        }
    
        return $max;
    }
    

    如果它因为没有 Count 标签而无法解决问题,那么它使用 imagick php 扩展。我采用双重方法的原因是因为后者很慢。

    【讨论】:

    • 这是一种固有的危险方法,肯定会在大量 PDF 文件上失败。其他方法速度较慢是有原因的 - 它们工作量更大,因此更可靠。
    【解决方案5】:

    您可以尝试 fpdi(请参阅here),正如您在设置源文件时看到的那样,您会返回页码。

    【讨论】:

    • 我在我的两台测试服务器(1 Win 和 1 Debian)上都进行了测试,结果都很好,所以我会接受它。
    • 我用这个尝试了一些 pdf,但 ImageMagick 似乎更可靠.. 对于许多 pdf,我得到:FPDF 错误:该文档 (test_1.pdf) 可能使用了免费解析器不支持的压缩技术与 FPDI 一起发货。
    • 我的错误信息与@Chris 的 FPDI 相同。部分 PDF 是使用 Adob​​e Pro 8/9 生成的。
    【解决方案6】:

    试试这个:

    <?php
    if (!$fp = @fopen($_REQUEST['file'],"r")) {
            echo 'failed opening file '.$_REQUEST['file'];
    }
    else {
            $max=0;
            while(!feof($fp)) {
                    $line = fgets($fp,255);
                    if (preg_match('/\/Count [0-9]+/', $line, $matches)){
                            preg_match('/[0-9]+/',$matches[0], $matches2);
                            if ($max<$matches2[0]) $max=$matches2[0];
                    }
            }
            fclose($fp);
    echo 'There '.($max<2?'is ':'are ').$max.' page'.($max<2?'':'s').' in '. $_REQUEST['file'].'.';
    }
    ?>
    

    Count 标签显示不同节点中的页面数。父节点在其 Count 标记中包含其他节点的总和,因此此脚本仅查找最大值(即页数)。

    【讨论】:

      【解决方案7】:

      这个不用imagick的:

      function getNumPagesInPDF($file) 
      {
          //http://www.hotscripts.com/forums/php/23533-how-now-get-number-pages-one-document-pdf.html
          if(!file_exists($file))return null;
          if (!$fp = @fopen($file,"r"))return null;
          $max=0;
          while(!feof($fp)) {
                  $line = fgets($fp,255);
                  if (preg_match('/\/Count [0-9]+/', $line, $matches)){
                          preg_match('/[0-9]+/',$matches[0], $matches2);
                          if ($max<$matches2[0]) $max=$matches2[0];
                  }
          }
          fclose($fp);
          return (int)$max;
      
      }
      

      【讨论】:

        【解决方案8】:
        function getNumPagesPdf($filepath) {
            $fp = @fopen(preg_replace("/\[(.*?)\]/i", "", $filepath), "r");
            $max = 0;
            if (!$fp) {
                return "Could not open file: $filepath";
            } else {
                while (!@feof($fp)) {
                    $line = @fgets($fp, 255);
                    if (preg_match('/\/Count [0-9]+/', $line, $matches)) {
                        preg_match('/[0-9]+/', $matches[0], $matches2);
                        if ($max < $matches2[0]) {
                            $max = trim($matches2[0]);
                            break;
                        }
                    }
                }
                @fclose($fp);
            }
        
            return $max;
        }
        

        这正是我想要的:

        我刚刚研究出这种获取 pdf 页码的方法... 在获得 pdf 页数后,我只需在 while 中添加中断,这样它就不会在这里陷入无限循环....

        【讨论】:

          【解决方案9】:

          在 *nix 环境下你可以使用:

          exec('pdftops ' . $filename . ' - | grep showpage | wc -l', $output);
          

          pdftops 的默认安装位置。

          或者按照 Xethron 的建议:

          pdfinfo filename.pdf | grep Pages: | awk '{print $2}'
          

          【讨论】:

          • -1,您的回答不符合“仅用 PHP 计算 PDF 中的页数”的问题。请注意“仅在 PHP 中”部分。 ;) 你的回答也是高度依赖系统的,无论是在安装的 *nix 还是 pdftops 上。
          • 极慢! pdfinfo filename.pdf | grep Pages: | awk '{print $2}' 是一个更好的解决方案!
          【解决方案10】:
          $pdftext = file_get_contents($caminho1);
          
           $num_pag = preg_match_all("/\/Page\W/", $pdftext,$dummy);
          

          【讨论】:

          • 我确信包含“/Page”的 PDF 很容易得到错误计数
          【解决方案11】:

          仅使用 PHP 会导致安装复杂的库、重新启动 Apache 等,并且许多纯 PHP 方式(如打开流和使用正则表达式)不准确

          包含的答案是我能想到的唯一快速可靠的方法。它使用单个可执行文件,但不必安装(*nix 或 Windows),并且一个简单的 PHP 脚本提取输出。最好的事情是我还没有看到错误的页数!

          可以在这里找到,包括为什么其他方法“不起作用”

          Get the number of pages in a PDF document

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2021-12-28
            • 2011-11-19
            • 2016-05-05
            • 2017-05-12
            • 2011-12-10
            • 2011-11-19
            • 1970-01-01
            相关资源
            最近更新 更多