获取 PDF 文档中的页数

2022-08-30 08:38:28

这个问题是用来参考和比较的。解决方案是下面接受的答案

我花了好几个小时搜索一种快速简便但大多准确的方法来获取PDF文档中的页数。由于我为一家经常使用PDF的图形印刷和复制公司工作,因此在处理文档之前必须精确地知道文档中的页数。PDF文档来自许多不同的客户端,因此它们不是使用相同的应用程序生成的和/或不使用相同的压缩方法。

以下是我发现的一些答案不足或根本不起作用

使用 Imagick(PHP 扩展名)

Imagick需要大量的安装,apache需要重新启动,当我最终让它工作时,它需要花费惊人的时间来处理(每个文档2-3分钟),并且它总是在每个文档中返回页面(到目前为止还没有看到Imagick的工作副本),所以我把它扔掉了。这两种方法都是如此。1getNumberImages()identifyImage()

使用 FPDI(一个 PHP 库)

FPDI易于使用和安装(只需提取文件并调用PHP脚本),FPDI不支持许多压缩技术。然后,它返回一个错误:

FPDF 错误:本文档(test_1.pdf)可能使用了 FPDI 附带的免费解析器不支持的压缩技术。

打开流并使用正则表达式进行搜索:

这将在流中打开 PDF 文件并搜索某种字符串,其中包含页数或类似内容。

$f = "test1.pdf";
$stream = fopen($f, "r");
$content = fread ($stream, filesize($f));

if(!$stream || !$content)
    return 0;

$count = 0;
// Regular Expressions found by Googling (all linked to SO answers):
$regex  = "/\/Count\s+(\d+)/";
$regex2 = "/\/Page\W*(\d+)/";
$regex3 = "/\/N\s+(\d+)/";

if(preg_match_all($regex, $content, $matches))
    $count = max($matches);

return $count;
  • /\/Count\s+(\d+)/(查找 )不起作用,因为只有少数文档内部有参数,因此大多数时候它不会返回任何内容。源。/Count <number>/Count
  • /\/Page\W*(\d+)/(查找 )不获取页数,主要包含一些其他数据。源。/Page<number>
  • /\/N\s+(\d+)/(查找 ) 也不起作用,因为文档可以包含 多个值 ;大多数(如果不是全部)不包含页数。源。/N <number>/N

那么,什么是可靠和准确的工作呢?

请参阅下面的答案


答案 1

一个简单的命令行可执行文件,称为:pdfinfo

它可以在Linux和Windows上下载。您下载一个包含几个与 PDF 相关的小程序的压缩文件。在某个地方提取它。

其中一个文件是pdfinfo(或pdfinfo.exe windows)。通过在 PDF 文档上运行数据返回的数据示例:

Title:          test1.pdf
Author:         John Smith
Creator:        PScript5.dll Version 5.2.2
Producer:       Acrobat Distiller 9.2.0 (Windows)
CreationDate:   01/09/13 19:46:57
ModDate:        01/09/13 19:46:57
Tagged:         yes
Form:           none
Pages:          13    <-- This is what we need
Encrypted:      no
Page size:      2384 x 3370 pts (A0)
File size:      17569259 bytes
Optimized:      yes
PDF version:    1.6

我还没有看到PDF文档返回错误的页数(尚未)。它也非常快,即使对于200 + MB的大文档,响应时间也只有几秒钟或更短的时间。

有一种从输出中提取页面计数的简单方法,在PHP中:

// Make a function for convenience 
function getPDFPages($document)
{
    $cmd = "/path/to/pdfinfo";           // Linux
    $cmd = "C:\\path\\to\\pdfinfo.exe";  // Windows
    
    // Parse entire output
    // Surround with double quotes if file name has spaces
    exec("$cmd \"$document\"", $output);

    // Iterate through lines
    $pagecount = 0;
    foreach($output as $op)
    {
        // Extract the number
        if(preg_match("/Pages:\s*(\d+)/i", $op, $matches) === 1)
        {
            $pagecount = intval($matches[1]);
            break;
        }
    }
    
    return $pagecount;
}

// Use the function
echo getPDFPages("test 1.pdf");  // Output: 13

当然,这个命令行工具可以在其他语言中使用,这些语言可以解析来自外部程序的输出,但我在PHP中使用它。

我知道它不是纯粹的PHP,但外部程序在PDF处理方面要好得多(如问题所示)。

我希望这可以帮助人们,因为我花了很多时间试图找到这个问题的解决方案,我看到很多关于PDF页面计数的问题,我没有找到我想要的答案。这就是为什么我提出这个问题并自己回答它。

安全声明:如果从用户输入或文件上传中获取文档名称,则用于。escapeshellarg$document


答案 2

最简单的是使用ImageMagick

这是一个示例代码

$image = new Imagick();
$image->pingImage('myPdfFile.pdf');
echo $image->getNumberImages();

否则,您也可以使用像 或 这样的库PDFMPDFTCPDFPHP


推荐