我花了很多时间寻找一种快速简便的,但主要是准确的,以获取PDF文档中的页数。由于我在一家使用PDF工作的图形打印和复制公司工作,因此在处理文档之前必须准确了解文档中的页数。 PDF文档来自许多不同的客户端,因此它们不是使用相同的应用程序生成的和/或不使用相同的压缩方法。
以下是我发现 不足 或只是 无效 的一些答案:
Imagick需要大量安装,apache需要重新启动,当我最终使用它时,处理时间非常长(每个文档2-3分钟)并且每个文档总是返回1
页面(到目前为止还没有看过Imagick的工作副本),所以我扔掉了。那是getNumberImages()
和identifyImage()
方法。
FPDI易于使用和安装(只提取文件并调用PHP脚本),但 FPDI不支持许多压缩技术。然后它返回一个错误:
FPDF错误:此文档(test_1.pdf)可能使用FPDI附带的免费解析器不支持的压缩技术。
这将在流中打开PDF文件并搜索某种类型的字符串,其中包含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>
)不起作用,因为只有少数文档内部有参数/Count
,因此大部分时间它都不会返回任何内容。 Source. /\/Page\W*(\d+)/
(查找/Page<number>
)没有得到页数,主要包含一些其他数据。 Source. /\/N\s+(\d+)/
(查找/N <number>
)也不起作用,因为文档可以包含多个/N
值;大多数(如果不是全部)不包含pagecount。 Source. 那么,什么工作可靠而准确?
答案 0 :(得分:80)
是downloadable for Linux and 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文档。它也非常快,即使有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 pagecount的问题,其中我找不到我想要的答案。这就是为什么我提出这个问题并自己回答。
答案 1 :(得分:16)
最简单的是使用 ImageMagick
这是一个示例代码
$image = new Imagick();
$image->pingImage('myPdfFile.pdf');
echo $image->getNumberImages();
否则您也可以使用PDF
或MPDF
等TCPDF
库来PHP
答案 2 :(得分:1)
如果您有权访问shell,则最简单(但不能在100%的PDF上使用)的方法是使用grep
。
这应该只返回页数:
grep -m 1 -aoP '(?<=\/N )\d+(?=\/)' file.pdf
示例:https://regex101.com/r/BrUTKn/1
切换说明:
-m 1
是必要的,因为一些文件可以有多个匹配的正则表达式模式(需要使用volonteer将其替换为仅匹配的第一个正则表达式解决方案扩展名) -a
是将二进制文件视为文本-o
仅显示匹配-P
使用Perl正则表达式正则表达式解释:
(?<=\/N )
/N
的后视(这里没有看到空格字符)\d+
任意位数(?=\/)
预见/
Nota bene:如果在某些情况下找不到匹配,则假设只有1页存在是安全的。
答案 3 :(得分:1)
由于可以使用命令行实用程序,因此可以使用cpdf(Microsoft Windows / Linux / Mac OS X)。要获取一份PDF中的页数:
cpdf.exe -pages "my file.pdf"
答案 4 :(得分:1)
您可以像下面一样使用qpdf
。如果file_name.pdf文件有100页,
$ qpdf --show-npages file_name.pdf
100
答案 5 :(得分:1)
我基于Richard的答案@
为pdfinfo创建了一个包装类,以防对任何人有用/**
* Wrapper for pdfinfo program, part of xpdf bundle
* http://www.xpdfreader.com/about.html
*
* this will put all pdfinfo output into keyed array, then make them accessible via getValue
*/
class PDFInfoWrapper {
const PDFINFO_CMD = 'pdfinfo';
/**
* keyed array to hold all the info
*/
protected $info = array();
/**
* raw output in case we need it
*/
public $raw = "";
/**
* Constructor
* @param string $filePath - path to file
*/
public function __construct($filePath) {
exec(self::PDFINFO_CMD . ' "' . $filePath . '"', $output);
//loop each line and split into key and value
foreach($output as $line) {
$colon = strpos($line, ':');
if($colon) {
$key = trim(substr($line, 0, $colon));
$val = trim(substr($line, $colon + 1));
//use strtolower to make case insensitive
$this->info[strtolower($key)] = $val;
}
}
//store the raw output
$this->raw = implode("\n", $output);
}
/**
* get a value
* @param string $key - key name, case insensitive
* @returns string value
*/
public function getValue($key) {
return @$this->info[strtolower($key)];
}
/**
* list all the keys
* @returns array of key names
*/
public function getAllKeys() {
return array_keys($this->info);
}
}
答案 6 :(得分:1)
这是一个简单的示例,可以通过PHP获取PDF的页数。
URLField
答案 7 :(得分:0)
如果您无法安装任何其他套餐,您可以使用这个简单的单行程序:
foundPages=$(strings < $PDF_FILE | sed -n 's|.*Count -\{0,1\}\([0-9]\{1,\}\).*|\1|p' | sort -rn | head -n 1)
答案 8 :(得分:0)
这是一个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")
}
答案 9 :(得分:0)
这是一个使用gsscript报告PDF文件页码
的Windows命令脚本@echo off
echo.
rem
rem this file: getlastpagenumber.cmd
rem version 0.1 from commander 2015-11-03
rem need Ghostscript e.g. 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
答案 10 :(得分:0)
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
答案 11 :(得分:0)
这似乎工作得很好,无需特殊包或解析命令输出。
<?php
$target_pdf = "multi-page-test.pdf";
$cmd = sprintf("identify %s", $target_pdf);
exec($cmd, $output);
$pages = count($output);