HOKKAPOKKA
@HOKKAPOKKA (HOKKA POKKA)

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

pdfファイルを開かずしてそのページ数を知るツールはないでしょうか

解決したいこと

pdfファイルを開かずしてそのページ数を知るツールはないでしょうか。
危険の無いOpen source等で開発された無料ツールで、アプリを開いてGUIからファイル→開く...といった類 ではなく、CUIでいいです。
Windows10のコマンドプロンプトから xxx.exe -x -y -z c:\hoge\hoge.pdf のような実行形式で、単にページ数だけが出力されるようなツールを探しています。

背景:
ダウンロードしたpdfファイルの中身をページごとに全copyして、他のテキストファイルに貼り付けるRPAを作ったが、何ページあるかを知ることで、ループの回数を設定する必要がある。
しょうがなくAdobe Readerで開いて印刷ページから最終ページを取得してみたが、なぜかそれがうまく行かず、
別の方法を模索しています。

自分で試したこと

ここに問題・エラーに対して試したことを記載してください。
いくつかシェアウェアを試しましたが、信用性が低いのと、すべてGUIでしたので利用をあきらめました。
たとえば、
https://www.vector.co.jp/soft/winnt/util/se409180.html?srsltid=AfmBOoolERfnogSIpb4dEtDgZOhs6MrfxDJ-bi_ih5bh85uUS3iLsnFr#google_vignette

0

1Answer

PDFのPage TreeノードのCountキーにはpageオブジェクトの数が設定されており、
その数はページ数と同じになるので、
適当なスクリプト言語等で取得する方法もあります。

テキストエディタで開いた時
image.png

PDFビューワーで開いた時
image.png

例:コマンドプロンプトからFindコマンドtest.pdf内の"/Count"を検索

>FIND "/Count" test.pdf

---------- TEST.PDF
/Count 7
4Like

Comments

  1. @HOKKAPOKKA

    Questioner

    コマンドプロンプトの方法はかなり理想的です。
    この例で言うと、"7"という数字だけが出てくるようにできないでしょうか。
    findstrみたいなものが使えないのかと思いまして。
    あるいは/Countからのオフセットが指定できる方法があるとか。

    また、この方法は万能ではないような気がしました。私の手元に23ページのtest_pagecount.pdfがあり、これで試しました。
    FIND "/Count" c:\temp\test_pagecount.pdf
    下記が出力結果です。
    ---------- C:\TEMP\TEST_PAGECOUNT.PDF
    /Kids [11 0 R 14 0 R 17 0 R 20 0 R 23 0 R 26 0 R 29 0 R 32 0 R 35 0 R 38 0 R 41 0 R 44 0 R 47 0 R 50 0 R 53 0 R 56 0 R 59 0 R 62 0 R 65 0 R 68 0 R 71 0 R 74 0000000000 65535 f

    実際にtypeしてみると
    (前略)
    <<
    /Type /Pages
    /Count 23
    /Kids [11 0 R 14 0 R 17 0 R 20 0 R 23 0 R 26 0 R 29 0 R 32 0 R 35 0 R 38 0 R 41 0 R 44 0 R 47 0 R 50 0 R 53 0 R 56 0 R 59 0 R 62 0 R 65 0 R 68 0 R 71 0 R 74 0 R 77 0 R ]

    (後略)
    よって、欲しい行の下の行が表示されているようです。
    この場合、"23"という数字だけが出力されるのが理想です。

  2. この例で言うと、"7"という数字だけが出てくるようにできないでしょうか。
    findstrみたいなものが使えないのかと思いまして。

    自分で調べれ貰えればいいかなと思っていましたが、
    一応下記にサンプルを記載しておきます。
    (特にテストをしたわけではないので、問題発生時は自己責任でお願いします。)

    下記のようなバッチファイルを作成して

    test.cmd
    @ECHO OFF
    FOR /F "usebackq tokens=2" %%i IN (`FINDSTR \/Count %1`) DO ECHO %%i
    

    下記のようにパラメータとしてPDFファイルのパスを渡す

    ファイル名指定
    >test.cmd test.pdf
    7
    
    パス指定
    >test.cmd "c:\test\test.pdf"
    7
    
  3. @HOKKAPOKKA

    Questioner

    @Yamazinさん、よくわかってなくて済みません。
    そもそも、このtest.cmdを試す前に、findの出力が前述の様に安定しないのです。
    試しに2ページのpdfでもfindを試しました。
    C:\TEMP>FIND "/Count" test2.pdf
    ---------- TEST2.PDF
    <>

    これだと
    C:\TEMP>test.cmd test2.pdf
    2/Kids[

  4. 2/Kids[

    PDFのファイル内で下記のように/Count 2の直後に/Kids[となっているため数字の後ろまで表示されているのだと思います。

    /Count 2/Kids[

    提示したサンプルでは後ろの文字までは考慮していないので
    後ろに数字以外があれば除外するような処理をいれれば、数字のみの表示になると思います。

    バッチファイルだと結構厳しいと思うので、
    PowerShellスクリプトのサンプルを記載しておきます。

    test.ps1
    $fileContent = Get-Content -Path $Args[0]
    
    $regex = [regex]"/Count (\d+)"
    $matches = $regex.Matches($fileContent)
    
    foreach ($match in $matches) {
        Write-Output $match.Groups[1].Value
    }
    
    >./test.ps1 test.pdf
    7
    
  5. @HOKKAPOKKA

    Questioner

    PowerShellはハードルが高いのであきらめますが、やはり以下の部分が
    腑に落ちないですね。23/Kids [... が出て来るならまだしも。
    (再掲)
    私の手元に23ページのtest_pagecount.pdfがあり、これで試しました。
    FIND "/Count" c:\temp\test_pagecount.pdf
    下記が出力結果です。
    ---------- C:\TEMP\TEST_PAGECOUNT.PDF
    /Kids [11 0 R 14 0 R 17 0 R 20 0 R 23 0 R 26 0 R 29 0 R 32 0 R 35 0 R 38 0 R 41 0 R 44 0 R 47 0 R 50 0 R 53 0 R 56 0 R 59 0 R 62 0 R 65 0 R 68 0 R 71 0 R 74 0000000000 65535 f

    実際にtypeしてみると
    (前略)
    <<
    /Type /Pages
    /Count 23
    /Kids [11 0 R 14 0 R 17 0 R 20 0 R 23 0 R 26 0 R 29 0 R 32 0 R 35 0 R 38 0 R 41 0 R 44 0 R 47 0 R 50 0 R 53 0 R 56 0 R 59 0 R 62 0 R 65 0 R 68 0 R 71 0 R 74 0 R 77 0 R ]

  6. PowerShellはハードルが高いのであきらめますが

    コマンドプロンプトのかわりにPowerShellを使うだけなのでハードルはバッチファイルとそんなに変わらないと思いますが

    最後に区切り文字を/にしたバッチファイルも書いておきます。
    (これも特にテストをしたわけではないので、問題発生時は自己責任でお願いします。)

    test2.cmd
    @ECHO OFF
    FOR /F "usebackq tokens=2 delims=/ " %%i IN (`FINDSTR \/Count %1`) DO ECHO %%i
    

    再掲された内容に関してはこちらでは確認できませんので回答は控えます。

  7. @HOKKAPOKKA

    Questioner

    やはりうまく行かないファイルの方が多くて残念です。
    3パターン位のPDFでメモ帳で開いて確認しました。
    /Type/Pages/Count 2/Kids[ 3 0 R 82 0 R]
    とか
    /Count 3/Kids [ 3 0 R 27 0 R 35 0 R ]/Type /Pages
    とか
    /Type /Pages/Count 23/Kids [11 0 R 14 0 R 17 0 R 20 0 R 23 0 R 26 0 R 29 0 R 32 0 R 35 0 R 38 0 R 41 0 R 44 0 R 47 0 R 50 0 R 53 0 R 56 0 R 59 0 R 62 0 R 65 0 R 68 0 R 71 0 R 74 0 R 77 0 R ]
    のパターンがありましたが。
    要するに"/Count "という文字列を探して、その直後にある数字で、かつ次の/の前を抽出できればいいんですね。そこの桁数が一定ではないので困ったものです。

  8. @HOKKAPOKKA

    Questioner

    Windows標準のコマンドでは難しそうなので、pdftkをインストールして使うことを検討しています。いろいろ調べた結果、以下でなんとかできそうです。
    for /f "tokens=2 delims=: " %A in ('pdftk abc.pdf dump_data ^| findstr "NumberOfPages"') do @echo %A
    いろいろアドバイスありがとうございました。

Your answer might help someone💌