获取PDF文档中的页数

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

我花了很多时间search一个快速简单,但大多数是准确的方法来获取PDF文档中的页数。 由于我工作的graphics打印和复制公司,与PDF工作了很多,一个文件中的页面数量必须精确知道之前,他们被处理。 PDF文档来自许多不同的客户端,所以它们不是由相同的应用程序生成的和/或不使用相同的压缩方法。

这里有一些答案我觉得不够或者根本就不行

使用Imagick (一个PHP扩展)

Imagick需要大量的安装,apache需要重新启动,当我最终工作时,花了很长时间来处理(每个文档2-3分钟),并且每个文档总是返回1页(没有看到工作Imagick迄今的副本),所以我把它扔了。 这是与getNumberImages()identifyImage()方法。

使用FPDI (一个PHP库)

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

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

打开一个stream并使用正则expression式进行search:

这将打开一个stream中的PDF文件,并search某种types的string,包含pagecount或类似的东西。

 $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> )不起作用,因为只有less数文档具有参数/Count内部,所以大部分时间不返回任何内容。 资源。
  • /\/Page\W*(\d+)/ (查找/Page<number> )不会获得页面的数量,大多包含一些其他的数据。 资源。
  • /\/N\s+(\d+)/ (查找/N <number> )也不起作用,因为文档可以包含多个/N值; 大部分(如果不是全部的话) 包含pagecount。 资源。

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

请参阅下面的答案

一个简单的命令行可执行文件叫做: pdfinfo

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

其中一个文件是pdfinfo (或Windows的pdfinfo.exe )。 通过在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文档,它返回了一个错误的pagecount(还)。 这也是非常快的,即使是200 + MB的大文件,响应时间只有几秒钟或更less。

有一个简单的方法从输出中提取pagecount,在这里用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 

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

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

我希望这可以帮助人们,因为我花了很多时间试图find解决办法,我看到了很多关于PDF pagecount的问题,我没有find我正在寻找的答案。 这就是为什么我自己提出这个问题并回答的原因。

最简单的就是使用ImageMagick

这里是一个示例代码

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

否则,你也可以使用PDF库,如MPDFTCPDFPHP

如果你不能安装任何额外的软件包,你可以使用这个简单的一行:

 foundPages=$(strings < $PDF_FILE | sed -n 's|.*Count -\{0,1\}\([0-9]\{1,\}\).*|\1|p' | sort -rn | head -n 1) 

这是一个R函数,它使用pdfinfo命令报告PDF文件的页码。

 pdf.file.page.number <- function(fname) { a <- pipe(paste("pdfinfo", fname, "| grep Pages | cut -d: -f2")) page.number <- as.numeric(readLines(a)) close(a) page.number } if (F) { pdf.file.page.number("a.pdf") } 

这是一个使用gsscript的Windows命令脚本,它报告PDF文件的页码

 @echo off echo. rem rem this file: getlastpagenumber.cmd rem version 0.1 from commander 2015-11-03 rem need Ghostscript eg download and install from http://www.ghostscript.com/download/ rem Install path "C:\prg\ghostscript" for using the script without changes \\ and have less problems with UAC rem :vars set __gs__="C:\prg\ghostscript\bin\gswin64c.exe" set __lastpagenumber__=1 set __pdffile__="%~1" set __pdffilename__="%~n1" set __datetime__=%date%%time% set __datetime__=%__datetime__:.=% set __datetime__=%__datetime__::=% set __datetime__=%__datetime__:,=% set __datetime__=%__datetime__:/=% set __datetime__=%__datetime__: =% set __tmpfile__="%tmp%\%~n0_%__datetime__%.tmp" :check if %__pdffile__%=="" goto error1 if not exist %__pdffile__% goto error2 if not exist %__gs__% goto error3 :main %__gs__% -dBATCH -dFirstPage=9999999 -dQUIET -dNODISPLAY -dNOPAUSE -sstdout=%__tmpfile__% %__pdffile__% FOR /F " tokens=2,3* usebackq delims=:" %%A IN (`findstr /i "number" test.txt`) DO set __lastpagenumber__=%%A set __lastpagenumber__=%__lastpagenumber__: =% if exist %__tmpfile__% del %__tmpfile__% :output echo The PDF-File: %__pdffilename__% contains %__lastpagenumber__% pages goto end :error1 echo no pdf file selected echo usage: %~n0 PDFFILE goto end :error2 echo no pdf file found echo usage: %~n0 PDFFILE goto end :error3 echo.can not find the ghostscript bin file echo. %__gs__% echo.please download it from: echo. http://www.ghostscript.com/download/ echo.and install to "C:\prg\ghostscript" goto end :end exit /b 

R包pdftools和函数pdf_info()提供有关pdf中页数的信息。

 library(pdftools) pdf_file <- file.path(R.home("doc"), "NEWS.pdf") info <- pdf_info(pdf_file) nbpages <- info[2] nbpages $pages [1] 65 

这似乎工作得很好,不需要特殊的包或parsing命令输出。

 <?php $target_pdf = "multi-page-test.pdf"; $cmd = sprintf("identify %s", $target_pdf); exec($cmd, $output); $pages = count($output); 

如果你有权访问shell,最简单的(但不能在100%的PDF上使用)的方法是使用grep

这应该只返回页面数量:

 grep -m 1 -aoP '(?<=\/N )\d+(?=\/)' file.pdf 

例如: https : //regex101.com/r/BrUTKn/1

开关描述:

  • -m 1是必要的,因为一些文件可以具有多于一个的正则expression式模式匹配(volonteer需要用匹配 – 第一正则expression式解决scheme扩展来replace它)
  • -a需要将二进制文件视为文本
  • -o只显示比赛
  • -P使用Perl正则expression式

正则expression式解释:

  • 开始“分隔符”: (?<=\/N ) /N (后面的空格字符在这里看不到)
  • 实际结果: \d+任意位数
  • 以“delimiter”结尾: (?=\/) lookahead of /

注意:如果在某些情况下没有find匹配,那么假设只存在1个页面是安全的。