J'ai passé de nombreuses heures à chercher un moyen rapide et facile, mais surtout le {exact, d'obtenir le nombre de pages d'un document PDF. Étant donné que je travaille pour une entreprise d’impression et de reproduction graphique qui travaille beaucoup avec les PDF, le nombre de pages d’un document doit être connu avec précision avant son traitement. PDF les documents proviennent de nombreux clients différents. Ils ne sont donc pas générés avec la même application et/ou n'utilisent pas la même méthode de compression.
Voici certaines des réponses que j'ai trouvées insuffisant ou tout simplement ne fonctionne pas:
Imagick nécessite beaucoup d’installation, Apache doit redémarrer, et quand j’ai enfin eu le temps de fonctionner, le traitement a pris un temps incroyable (2 à 3 minutes par document) et il retournait toujours la page 1
dans chaque document copie d’Imagick jusqu’à présent), alors je l’ai jeté. C'était avec les méthodes getNumberImages()
et identifyImage()
.
FPDI est facile à utiliser et à installer (il suffit d'extraire des fichiers et d'appeler un script PHP), MAIS de nombreuses techniques de compression ne sont pas prises en charge par FPDI. Il retourne ensuite une erreur:
Erreur FPDF: Ce document (test_1.pdf) utilise probablement une technique de compression qui n’est pas prise en charge par l’analyseur gratuit fourni avec FPDI.
Cela ouvre le fichier PDF dans un flux et recherche un type de chaîne contenant le nombre de pages ou quelque chose de similaire.
$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+)/
(cherche /Count <number>
) ne fonctionne pas car seuls quelques documents ont le paramètre /Count
à l'intérieur, de sorte que la plupart du temps, ils ne renvoient rien. La source./\/Page\W*(\d+)/
(cherche /Page<number>
) n'obtient pas le nombre de pages, contient la plupart du temps d'autres données. La source./\/N\s+(\d+)/
(cherche /N <number>
) ne fonctionne pas non plus, car les documents peuvent contenir plusieurs valeurs de /N
; la plupart sinon la totalité pas contenant le nombre de pages. La source.Alors, qu'est-ce que le travail est fiable et précis?
Il est téléchargeable pour Linux et Windows . Vous téléchargez un fichier compressé contenant plusieurs petits programmes liés à PDF. Extrait-le quelque part.
Un de ces fichiers est pdfinfo (ou pdfinfo.exe pour Windows). Un exemple de données renvoyées en l’exécutant sur un PDF document:
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
Je n'ai pas vu un PDF document où il a retourné un faux numéro de page (pour le moment). Il est également très rapide, même avec des documents volumineux de plus de 200 Mo. Le temps de réponse est de quelques secondes ou moins.
Il existe un moyen simple d'extraire le nombre de pages de la sortie, ici en 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
Bien sûr, cet outil de ligne de commande peut être utilisé dans d'autres langages pouvant analyser les résultats d'un programme externe, mais je l'utilise en PHP.
Je sais que ce n'est pas pur PHP, mais les programmes externes sont chemin meilleurs en PDF traitement (comme on le voit dans la question).
J'espère que cela pourra aider les gens, car j'ai passé beaucoup de temps à essayer de trouver la solution et j'ai vu beaucoup de questions sur PDF pagecount dans lesquelles je n'ai pas trouvé de réponse. cherchais. C'est pourquoi j'ai posé cette question et y ai répondu moi-même.
Le plus simple est d'utiliser ImageMagick
voici un exemple de code
$image = new Imagick();
$image->pingImage('myPdfFile.pdf');
echo $image->getNumberImages();
sinon, vous pouvez également utiliser les bibliothèques PDF
telles que MPDF
ou TCPDF
pour PHP
Si vous avez accès à Shell, une approche plus simple (mais non utilisable sur 100% des fichiers PDF) consiste à utiliser grep
.
Cela devrait renvoyer uniquement le nombre de pages:
grep -m 1 -aoP '(?<=\/N )\d+(?=\/)' file.pdf
Exemple: https://regex101.com/r/BrUTKn/1
Description des commutateurs:
-m 1
est nécessaire car certains fichiers peuvent avoir plusieurs correspondances de motif de regex (volonteer de le remplacer par une extension de solution correspondant uniquement au premier regex)-a
est nécessaire pour traiter le fichier binaire en tant que texte-o
pour afficher uniquement la correspondance-P
pour utiliser l'expression régulière PerlExplication regex:
(?<=\/N )
lookbehind de /N
(nb. espace non visible ici)\d+
n'importe quel nombre de chiffres(?=\/)
lookahead de /
Remarque: si, dans certains cas, aucune correspondance n'est trouvée, il est prudent de supposer qu'une seule page existe.
Puisque vous utilisez les utilitaires de ligne de commande, vous pouvez utiliser cpdf (Microsoft Windows/Linux/Mac OS X). Pour obtenir le nombre de pages dans un PDF:
cpdf.exe -pages "my file.pdf"
Vous pouvez utiliser qpdf
comme ci-dessous. Si un fichier nom_fichier.pdf comporte 100 pages,
$ qpdf --show-npages file_name.pdf
100
Cela semble fonctionner assez bien, sans avoir besoin de paquetages spéciaux ni de sortie de commande d'analyse.
<?php
$target_pdf = "multi-page-test.pdf";
$cmd = sprintf("identify %s", $target_pdf);
exec($cmd, $output);
$pages = count($output);
Voici une fonction R
qui indique le numéro de page du fichier PDF à l’aide de la commande 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")
}
si vous ne pouvez installer aucun paquet supplémentaire, vous pouvez utiliser ce simple one-liner:
foundPages=$(strings < $PDF_FILE | sed -n 's|.*Count -\{0,1\}\([0-9]\{1,\}\).*|\1|p' | sort -rn | head -n 1)
Le package R pdftools et la fonction pdf_info()
fournissent des informations sur le nombre de pages d'un fichier PDF.
library(pdftools)
pdf_file <- file.path(R.home("doc"), "NEWS.pdf")
info <- pdf_info(pdf_file)
nbpages <- info[2]
nbpages
$pages
[1] 65
Voici un script de commande Windows utilisant gsscript indiquant le numéro de page du fichier 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