71

この質問は、参照と比較のためのものです。解決策は、以下の受け入れられた回答です。

PDFドキュメントのページ数を取得するための、高速で簡単ですが、ほとんど正確な方法を何時間も探しました。私は、PDF を頻繁に扱うグラフィック印刷および複製会社で働いているため、文書を処理する前に、文書内のページ数を正確に把握する必要があります。PDF ドキュメントはさまざまなクライアントから提供されるため、同じアプリケーションで生成されていないか、同じ圧縮方法を使用していません。

以下は、私が不十分である、または単に機能していないことがわかった回答の一部です。

Imagick (PHP 拡張機能) の使用

Imagick には多くのインストールが必要で、apache を再起動する必要があり、最終的に機能するようになったとき、処理に驚くほど時間がかかり (ドキュメントごとに 2 ~ 3 分) 1、すべてのドキュメントで常にページが返されました (作業コピーが表示されていません)。これまでのImagickの)なので、捨てました。それはgetNumberImages()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+)/(looks for /Count <number>) は機能しません。内部にパラメーターが含まれているドキュメントはごくわずかであり/Count、ほとんどの場合、何も返されません。ソース。
  • /\/Page\W*(\d+)/( を探します/Page<number>) はページ数を取得しません。ほとんどの場合、他のデータが含まれています。ソース。
  • /\/N\s+(\d+)/ドキュメントには;の複数の値を含めることができるため、 (looks for /N <number>) も機能しません。/N すべてではないにしても、ほとんどの場合、ページ数は含まれていません。ソース。

では、信頼性が高く正確な作業とは何でしょうか?

以下の回答を参照してください

4

15 に答える 15

104

pdfinfoと呼ばれる単純なコマンドライン実行可能ファイル。

Linux および Windows 用にダウンロード可能です。いくつかの小さな PDF 関連プログラムを含む圧縮ファイルをダウンロードします。どこかで抽出してください。

それらのファイルの 1 つが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 処理においてはるかに優れています (質問に見られるように)

私はこれに対する解決策を見つけるために多くの時間を費やしてきたので、これが人々の助けになることを願っています. そのため、私はこの質問を作成し、自分で答えました。

セキュリティ通知:ドキュメント名がユーザー入力またはファイル アップロードから供給されている場合escapeshellargに onを使用します。$document

于 2013-02-01T10:33:13.213 に答える
1

この単純な 1 ライナーはうまく機能しているようです。

strings $path_to_pdf | grep Kids | grep -o R | wc -l

PDF ファイルには、このファンキーな文字列のページ数を詳述するブロックがあります。

/Kids [3 0 R 4 0 R 5 0 R 6 0 R 7 0 R 8 0 R 9 0 R 10 0 R 11 0 R 12 0 R 13 0 R 14 0 R 15 0 R 16 0 R 17 0 R 18 0 R 19 0 R 20 0 R 21 0 R 22 0 R 23 0 R 24 0 R 25 0 R 26 0 R 27 0 R 28 0 R 29 0 R 30 0 R 31 0 R 32 0 R 33 0 R 34 0 R 35 0 R 36 0 R 37 0 R 38 0 R 39 0 R 40 0 R 41 0 R]

「R」の文字数がページ数

文字列からの出力を示す端末のスクリーンショット

于 2021-08-22T21:45:42.283 に答える
0

Rコマンドを使用して PDF ファイルのページ番号を報告する関数を次に示しますpdfinfo

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")
}
于 2015-08-13T19:41:54.570 に答える
0

シェルにアクセスできる場合、最も簡単な (ただし 100% の PDF では使用できない) 方法は、grep.

これはページ数だけを返すはずです:

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

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

スイッチの説明:

  • -m 1一部のファイルには正規表現パターンの一致が複数ある可能性があるため、これが必要です (これを最初の一致のみの正規表現ソリューション拡張子に置き換えるためにボランティアが必要です)
  • -aバイナリファイルをテキストとして扱う必要があります
  • -o一致のみを表示するには
  • -PPerl 正規表現を使用するには

正規表現の説明:

  • 「区切り文字」の開始:(?<=\/N )後読み/N(ここではスペース文字は表示されません)
  • 実際の結果:\d+任意の桁数
  • 末尾の「区切り文字」:(?=\/)先読み/

注: 場合によっては一致が見つからない場合は、1 ページのみが存在すると想定しても問題ありません。

于 2017-06-21T15:57:13.907 に答える
0

これは、PDF ファイルのページ番号を報告する gsscript を使用した 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
于 2015-11-03T00:17:06.233 に答える
-1

多くの場合、正規表現を読みます/\/Page\W/が、いくつかの pdf ファイルでは機能しません。だからここに私のために働く他の正規表現があります。

$pdf = file_get_contents($path_pdf);
return preg_match_all("/[<|>][\r\n|\r|\n]*\/Type\s*\/Page\W/", $path_pdf, $dummy);
于 2021-12-31T09:09:17.097 に答える