71 votes

Obtenir le nombre de pages d'un document PDF

Cette question porte sur le référencement et la comparaison. La solution est la réponse acceptée ci-dessous .

J'ai passé de nombreuses heures à chercher une solution rapide et facile, mais surtout précis Il s'agit d'un moyen d'obtenir le nombre de pages d'un document PDF. Comme je travaille pour une entreprise d'impression et de reproduction graphique qui travaille beaucoup avec des PDF, le nombre de pages d'un document doit être connu avec précision avant de le traiter. Les documents PDF 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 quelques-unes des réponses que j'ai trouvées insuffisante ou simplement Ne fonctionne pas :

Utilisation de Imagick (une extension PHP)

Imagick nécessite beaucoup d'installation, apache doit être redémarré, et lorsque j'ai finalement réussi à le faire fonctionner, le traitement était incroyablement long (2 à 3 minutes par document) et renvoyait toujours les résultats suivants 1 dans chaque document (je n'ai pas vu de copie fonctionnelle d'Imagick jusqu'à présent), alors je l'ai jeté. C'était à la fois avec le getNumberImages() y identifyImage() méthodes.

Utilisation de FPDI (une bibliothèque PHP)

FPDI est facile à utiliser et à installer (il suffit d'extraire les fichiers et d'appeler un script PHP), MAIS de nombreuses techniques de compression ne sont pas prises en charge par FPDI. Il renvoie alors une erreur :

Erreur FPDF : Ce document (test_1.pdf) utilise probablement une technique de compression qui n'est pas supportée par l'analyseur libre livré avec FPDI.

Ouverture d'un flux et recherche avec une expression régulière :

Cela ouvre le fichier PDF dans un flux et recherche une sorte 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 possèdent le paramètre /Count à l'intérieur, donc la plupart du temps, il ne renvoie rien. Source.
  • /\/Page\W*(\d+)/ (cherche /Page<number> ) ne donne pas le nombre de pages, mais contient surtout d'autres données. Source.
  • /\/N\s+(\d+)/ (cherche /N <number> ) ne fonctionne pas non plus, car les documents peuvent contenir plusieurs valeurs de /N ; la plupart, sinon tous, pas contenant le nombre de pages. Source.

Alors, qu'est-ce qu'un travail fiable et précis ?

Voir la réponse ci-dessous

104voto

GeenHenk Points 1494

Un simple exécutable de ligne de commande appelé : pdfinfo .

Il est téléchargeable pour Linux et Windows . Vous téléchargez un fichier compressé contenant plusieurs petits programmes relatifs aux PDF. Extrayez-le quelque part.

L'un de ces fichiers est pdfinfo (ou pdfinfo.exe pour Windows). Un exemple de données retournées en l'exécutant sur un document 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

Je n'ai pas vu de document PDF où il a retourné un faux compte de pages (encore). Il est également très rapide, même avec des documents de plus de 200 Mo, le temps de réponse n'est que 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 en ligne de commande peut être utilisé dans d'autres langages qui peuvent analyser la sortie d'un programme externe, mais je l'utilise en PHP.

Je sais que ce n'est pas du pur PHP mais les programmes externes sont chemin meilleur dans la gestion des PDF (comme indiqué dans la question).

J'espère que cela pourra aider les gens, car j'ai passé beaucoup de temps à essayer de trouver la solution à ce problème et j'ai vu beaucoup de questions sur le pagecount PDF dans lesquelles je n'ai pas trouvé la réponse que je cherchais. C'est pourquoi j'ai posé cette question et y ai répondu moi-même.

Avis de sécurité : Utilisez escapeshellarg sur $document si le nom du document provient d'une entrée utilisateur ou d'un téléchargement de fichier.

12 votes

+1 Pour avoir pris le temps d'aider la communauté et pour avoir partagé vos connaissances acquises à la suite de ce problème.

0 votes

Comme alternative (si pdfinfo n'est pas disponible sur le serveur), vous pouvez aussi utiliser pdftk avec le dump_data option. Il vous suffit d'effectuer quelques modifications : - Définir la variable $cmd comme étant le binaire pdftk - Changer l'appel preg_match de Pages a NumberOfPages Et c'est tout :-)

0 votes

@bouchon - C'est sûr que ça ressemble à quelque chose de sympa (le serveur en fait, le reste a une interface graphique), bien que vous deviez l'installer. pdfinfo est un seul fichier binaire. Il suffit de le télécharger et de le placer n'importe où (par exemple, à côté de votre script PHP pour un accès facile).

27voto

Kuldeep Dangi Points 1744

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 aussi utiliser PDF des bibliothèques comme MPDF o TCPDF para PHP

10voto

Trying2Learn Points 11

Vous pouvez utiliser qpdf comme ci-dessous. Si un fichier nom_fichier.pdf a 100 pages,

$ qpdf --show-npages file_name.pdf
100

3voto

purvik7373 Points 2791

Voici un exemple simple pour obtenir le nombre de pages d'un PDF avec PHP.

<?php

function count_pdf_pages($pdfname) {
  $pdftext = file_get_contents($pdfname);
  $num = preg_match_all("/\/Page\W/", $pdftext, $dummy);

  return $num;
}

$pdfname = 'example.pdf'; // Put your PDF path
$pages = count_pdf_pages($pdfname);

echo $pages;

?>

2voto

Muad'Dib Points 23

Si vous ne pouvez pas installer de paquets supplémentaires, vous pouvez utiliser cette simple ligne unique :

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

0 votes

Pourriez-vous expliquer ce qu'il fait et ce dont il a besoin ? Qu'est-ce que le sed -n , sort -rn y head -n ? Il semble également que vous cherchiez /Count <number> que j'ai montré dans ma question, ne fonctionne pas.

1 votes

Strings - récupère toutes les chaînes de caractères du binaire PDF. Sed - correspond aux valeurs trouvées dans les chaînes 'Count'. Le (-n), lorsqu'il est utilisé en conjonction avec (p)rint, évitera la répétition de l'impression des lignes. sort - prend les valeurs 'Count' trouvées et les trie dans l'ordre (-r)everse, en traitant chaque valeur comme un (n)umbre (descendant). head - imprime les -n premiers numéros de ligne. Dans ce cas, 1 (la valeur par défaut est 10), qui sera la valeur de 'Count' la plus élevée. Je ne suis jamais tombé sur un PDF qui n'avait pas de valeur Count. Ce n'est que de la chance, je suppose. Avez-vous vérifié que votre expression rationnelle fonctionne correctement en dehors de preg_match_all ?

2 votes

Merci pour votre explication. Oui, je l'ai fait. J'ai testé un grand nombre de PDF à ce sujet (car je travaille principalement avec des PDF, environ 100 par jour) et environ 40 % de tous les PDF ont effectivement l'attribut Count valeur. J'ai également testé cela en écrivant simplement le flux dans un fichier texte et en le recherchant (ou même des parties de celui-ci) manuellement. Sur certains PDF, je l'ai trouvé, mais sur la plupart des PDF, je ne l'ai pas trouvé.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X