Узнать количество страниц в PDF-документе



этот вопрос для ссылки и сравнения. Решение-это принятый ответ ниже.



много часов я искал быстро и легко, но в основном точный, способ получения количества страниц в PDF-документе. Поскольку я работаю в графической полиграфической и репродукционной компании, которая много работает с PDF-файлами, количество страниц в документе должно быть точно известно до их обработки. PDF документы приходят из разных источников клиенты, поэтому они не генерируются с одним и тем же приложением и/или не используют один и тот же метод сжатия.



вот некоторые из ответов, которые я нашел недостаточно или просто не работает:



используя Imagick (расширение PHP)



Imagick требует много установки, apache нужно перезапустить, и когда я, наконец, работал, это заняло удивительно много времени для обработки (2-3 минут на документ) и он всегда возвращался 1 страница в каждом документе (до сих пор не видел рабочей копии Imagick), поэтому я ее выбросил. Это было с обоими getNumberImages() и identifyImage() методы.



используя FPDI (библиотека PHP)



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 = "//Counts+(d+)/";
$regex2 = "//PageW*(d+)/";
$regex3 = "//Ns+(d+)/";

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

return $count;




  • //Counts+(d+)/ (ищет /Count <number>) не работает, потому что есть только несколько документов параметр /Count внутри, поэтому большую часть времени он не возвращает ничего. Источник.


  • //PageW*(d+)/ (ищет /Page<number>) не получает количество страниц, в основном содержит некоторые другие данные. Источник.


  • //Ns+(d+)/ (ищет /N <number>) не работает, так как документы могут содержать несколько значений /N; большинство, если не все, не содержащий pagecount. Источник.





Итак, что же работает надежно и точно?



смотрите ответ ниже


2599   8  

8 ответов:

простой исполняемый файл командной строки: 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 время отклика составляет всего несколько секунд или меньше.

существует простой способ извлечения 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

конечно, этот инструмент командной строки может использоваться на других языках, которые могут анализировать вывод из внешней программы, но я использую его в PHP.

Я знаю, что это не чистый PHP, но внешние программы путь лучше в обработке PDF (как видно из вопроса).

Я надеюсь, что это может помочь людям, потому что я потратил много времени, пытаясь найти решение для этого, и я видел много вопросов о PDF pagecount, в которых я не нашел ответа, который искал. Вот почему я задал этот вопрос и сам на него ответил.

проще всего использовать ImageMagick

вот пример кода

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

в противном случае вы можете также использовать PDF библиотеки MPDF или TCPDF на PHP

если у вас есть доступ к оболочке, самый простой (но не используемый на 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 ) lookbehind of /N (nb. пробел не видел здесь)
  • фактический результат: \d+ любое число цифр
  • заканчивая "разделитель": (?=\/) перспективной /

Nota bene: если в каком-то случае совпадение не найдено, можно с уверенностью предположить, что существует только 1 страница.

Если вы не можете установить какие-либо дополнительные пакеты, вы можете использовать этот простой фразой:

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

здесь R функция, которая сообщает номер страницы 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")
}

вот командный скрипт Windows с использованием gsscript, который сообщает номер страницы PDF-файла

@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

пакет R pdftools и предоставляет информацию о количестве страниц в формате PDF.

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

$pages
[1] 65

это, кажется, работает довольно хорошо, без необходимости специальных пакетов или вывода команды разбора.

<?php                                                                               

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

Comments

    Ничего не найдено.