Commentaires sur l'article Créer un fichier PDF avec PHP

Oki, bien noté, merci Patrice.

Olivier O. à 11h07

J'ai beaucoup appréciez la description de création de fichiers pdf mais j'aurai voulu garder le conctact avec afin d'avoir plus d'information si je peux me permettre de dire formation help me

matrix128bit à 09h30

Bonjours matrix128bit,

Que voulez savoir de plus ? Je ne fais pas de formation, je n'ai pas de temps pour ça.
Le mieux est de prendre du temps et de tester petit à petit pour arriver à ce que l'on veux comme résultat.

Patrice à 17h38

Bonjour,

Tout d'abord merci pour ce tuto très bien construit et pour ce code bien utile !
Je rencontrecependant plusieurs problèmes ...

Le premier étant que je ne comprend pas trop l'URL que l'on doit appeler, est-ce :
http://lesite.fr/index.php?id=0&download=nomdufichier

Le second est que lorsque j'appelle cette URL j'obtient une erreur php :

Notice: Undefined variable: yMax in C:\wamp\www\pdf\facturePDF.php on line 298


Encore une fois merci pour votre aide :D

AlexandreRideau à 11h44

Bonjour Alexandre,

Content que cet exemple puisse servir.

Je ne suis pas sûr d'avoir compris la question à propos de l'URL, mais il n'y en a pas à proprement parler. Je vous fourni une classe PHP que vous devez inclure et initialiser dans un fichier PHP.

<?php
// importe la class facturePDF qui va elle-même charger FPDF
require('facturePDF.php');
?>

Quand à l'erreur vous pouvez la corriger en ajouter $yMax = 0;
Voici la fonction complète corrigée :

function Header(){
$yMax = 0;
if(!empty($this->logoUrl)){
$this->Image($this->logoUrl, $this->logoPosX, $this->logoPosY, $this->logoWidth);
$this->Ln(12);
}
// elements d'entete
foreach($this->elementLst['header'] as $v){
$yMax = max($yMax, $this->prepareLine($v['text'], $this->template[$v['id']]));
}
// entete du tableau
if(!empty($this->productHead)){
$this->SetY($yMax);
$tplt = $this->template['productHead'];
$this->buildLine($this->productWidth, $tplt['lineHeight'], $this->productHead, $this->productHead, $tplt, $tplt['color'], $tplt['backgroundColor']);
}
}

Vous ne devriez plus avoir d'erreur à présent.

Patrice à 15h47

Merci beaucoup Patrice, je confirme que celà fonctionne correctement maintenant.
Excusez-moi pour le dérangement, je pense que j'aurais pu corriger ce bug tout seul ...


Je rencontre cependant un problème que j'ai déjà rencontré sur d'autre script fpdf, lorsqu'il y à trop de lignes pour le tableau de la première page, les suivantes se créent sur la page d'après.
Le problème étant que ces lignes "débordent" sur le footer et je n'arrive pas à comprendre comment les en empêcher ...

En tout cas merci pour votre première réponse trés rapide !

xD

AlexandreRideau à 16h09

* :D

AlexandreRideau à 09h53

Bonjour Alexandre,

Effectivement il doit y avoir des ratés au passage d'une nouvelle page, la classe ajoute les lignes les unes après les autres, je l'avais conçu pour des factures d'une page.

Il faudrait modifier un peu la fonction buildPDF pour vérifier s'il y a la place pour ajouter une ligne. Pour cela il faudrait calculer la hauteur du pied de page et l'enregistrer dans une variables. Puis faire la soustraction.

Vous pensez y arriver ?

Patrice à 14h29

Bonjour Patrice,

En effet c'est bien ce que je pensais, mais j'avoue galérer un peut n'étant pas un "pro" de fpdf ...

Je ne comprend pas trop comment faire pour calculer la hauteur du pied de page.


J'essaye aussi d'afficher le numéro de page en haut à droite là où est écrit "Page" mais n'y arrive pas non plus.


En tout cas merci pour toute votre aide :-)

AlexandreRideau à 14h43

Pour avoir le numéro de page il faut utiliser la fonction PageNo()
<?php
require('fpdf.php');
$pdf = new FPDF();
$pdf->Cell(0, 10, 'Page '.$pdf->PageNo(), 0, 0, 'C');
$pdf->Output();
?>

Vous pouvez utiliser le texte '{nb}' pour afficher le nombre de page total du document.
$pdf->Cell(0, 10, 'Page '.$pdf->PageNo(.'/{nb}'), 0, 0, 'C');


Je vais corriger le bug des multi-pages dans les semaines prochaines parce que j'en aurais besoin sur un autre projet ;-)

Patrice à 15h05

Ok cool.

Bon si jamais j'y arrive avant je vous le dirais.

Merci à vous :-)

AlexandreRideau à 15h16

Bonjour Patrice,

Merci pour ce tuto !

Des indications particulières pour faire apparaitre des bordures autour des tableaux créés dans le pdf ?

J'avoue être en train de me battre avec en ce moment, et je vois que tu avais l'intention de partager des informations à ce propos.

Est-ce toujours d'actualité ?

Merci à toi !

Adrien à 12h25

Bonjour Adrien,

Je n'ai pas travaillé sur ce point depuis.
Il faut modifier la fonction buildLine(), à la ligne 228.
C'est ici que le fond de la cellule est dessiné.
Tu peux remplacer :
$this->Rect($aTplt['margin'][3], $this->GetY()+$aTplt['margin'][0], $aW+$aTplt['padding'][1]+$aTplt['padding'][3], $aH+$aTplt['padding'][0]+$aTplt['padding'][2], 'F');

Par : $this->Rect($aTplt['margin'][3], $this->GetY()+$aTplt['margin'][0], $aW+$aTplt['padding'][1]+$aTplt['padding'][3], $aH+$aTplt['padding'][0]+$aTplt['padding'][2], 'D');

Plutôt que de remplir ('F'), le rectangle va être dessiné ('D')

Plus d'info :
http://www.fpdf.org/en/doc/rect.htm

C'est du bricolage mais c'est pour l'idée ;-)

A noter que je n'ai pas testé, il faut peut-être modifier l'épaisseur et / ou la couleur du trait.

Patrice à 12h43

Je te remercie beaucoup pour cette réponse, je vais essayer tout ça :)

Adrien à 15h47

Je vois donc à peu près le principe.

En fait, souhaitant mettre un espèce de quadrillage pour une facture, je pense que le mieux est de repartir sur la définition des cellules qui composent le tableau le représentant.

Adrien à 16h10

Oui dans ce cas il faut modifier le code un tout petit plus loin.
Ligne 236. C'est dans cette boucle foreach que les cellules d'une ligne de produit sont affichées.

D'ailleur la fonction MultiCell permet de dessiner une bordure :
http://www.fpdf.org/fr/doc/multicell.htm

Mais tu perds la notion de padding et margin je pense.

Patrice à 11h41

En effet.

Je pense que le mieux est de repartir sur une création de cellules individuelles peut-être.

Adrien à 14h14

j'essaye de compiler le fichiers mais toujours un probléme au niveau de fichier faturePDF:
Fatal error: Call to undefined method facturePDF::FPDF() in C:\xampp\htdocs\TD\facturePDF.php on line 29

khalid btb à 03h44

Bonjour khalid btb,

La librairie FPDF est correctement chargée ?
La ligne 29 "$this->FPDF();" c'est l'appel au constructeur.

Patrice à 09h17

Bonjour,

J'ai aussi le message d’erreur suivant :

Call to undefined method facturePDF::FPDF()

je n'arrive pas à trouver le problème merci de bien vouloir me conseiller ...

alf à 19h23

Bonsoir alf,

Question bête, mais le fichier est correctement chargé ?
Ligne 1 tu peux ajouter un simple echo "FICHIER CHARGÉ";

Patrice à 19h40

C'est un serveur Microsoft ou Apache ?

Patrice à 19h42

Pour l'erreur de la ligne 29, c'est parce qu'il faut appeler le constructeur parent de cette manière :

parent::__construct();

remplacez donc :
$this->FPDF();
par :
parent::__construct();


Merci à Patrice pour ce super tuto !

Raph à 12h09

Merci Raph, j'ai corrigé les fichiers pour prendre en compte cette remarque.

Patrice à 21h56

Bonjour Patrice,
Permet moi de te remercier pour ce super tuto.
Ma question est la suivante : avec cette bibliothèque est ce qu'on peut sécuriser par mot de passe le fichier pdf produit.
Pour la lecture, l'impression.... qu'on demande un mot de passe ?
Si cette bibliothèque ne le fait pas connaissez vous une autre bibliothèque qui peut le faire ?

Merci d'avance

lansana à 15h08

Bonjour lansana,

Oui c'est possible, voir ce lien :
[url]http://www.fpdf.org/en/script/script37.php[/url]

Patrice à 14h28

Bonjour Patrice,

Il faut simplement excuser mon côté un peu débutant : je pense avoir fait tout ce qu'il fallait en ayant notamment chargé la version fpdf 1.81...
Ai fait le correctif $yMax = 0; car j'avais la même erreur que Alexandre.

j'ai cette erreur que je ne parviens pas à débuger par moi-même :
Notice: Undefined index: download in C:\...\facturePDF\index.php on line 55

Est-ce que tu as une solution ?

Grand Merci par avance et très beau tuto

Guillaume

Guillaume à 18h30

Patrice,

Toutes mes excuses... je n'avais pas assez fouillé... j'ai trouvé par moi-même une solution en relisant ton tuto au bon endroit...

Grand Merci encore...

Guillaume

Guillaume à 18h38

Bien joué Guillaume :-)

Patrice à 19h38

Bonjour et merci pour ce magnifique tuto qui m'a sauvé la vie:-).

Je n'arrive pas à afficher les bordures des tableaux.
est ce que vous pouvez m'aider ou m'orienter ?

merci d'avance.

Stephan à 16h27

Bonsoir Stephan,

FPDF permet de dessiner des bordures sur les cellules :
[url]http://www.fpdf.org/en/doc/cell.htm[/url]

Mais je n'ai pas testé.
Si ça ne fonctionne pas, vous pouvez essayer de dessiner un rectangle autour des cellules avec rect :
http://www.fpdf.org/fr/doc/rect.htm

Patrice à 17h35

Bonjour,
tout en esperant que quelqu'un suit ce forum.
j'ai quelques erreurs dans la generation de ma facture..
- Notice: Undefined offset: 2 in C:\wamp\www\PROGEST\facturePDF\facturePDF.php on line 237
- Notice: Undefined offset: 2 in C:\wamp\www\PROGEST\facturePDF\facturePDF.php on line 241
- Fatal error: Uncaught exception 'Exception' with message 'FPDF error: Some data has already been output, can't send PDF file (output started at C:\wamp\www\PROGEST\facturePDF\facturePDF.php:241)' in C:\wamp\www\PROGEST\facturePDF\fpdf.php on line 271
- Notice: Undefined index: download in C:\wamp\www\PROGEST\facturePDF\index.php on line 78.
SI quelqu'un a une idée s'il vous plait!

maliwari à 16h34

Bonjour maliwari,

Première et deuxième erreur : ligne 237 et 241 ça vient de $aHeader[$k]['width'] qui n'est pas définit. Il faut donc le définir avec productHeaderAddRow();
La troisième erreur c'est normal. Des entêtes ont déjà été envoyé, donc on ne peut pas les rechanger.
L'erreur à la ligne 78 d'index.php je ne sais pas. A toi de la trouver et de la corriger ;-)

Patrice à 17h08

Bonjour Patrice,
Merci pour la réponse ...
Je vais essayer de corriger les deux premières erreurs.
Pour le problème de la ligne 78, je ne sais vraiment pas comment le gérer car dans certaines versions de wampserver ça fonctionne(ancienne version, 2.0.5 par exple) mais ça marche pas avec la version 3.0.6 et je ne sais pas pourquoi?
Même pour les gabarits j'avais les mêmes soucis au niveau $_GET['id']. Des que je change de version de wampserver tous ces problèmes ont apparu. Avec mon ancienne version, tout se passe a merveille.
Merci pour le coup de main!

maliwari à 08h34

Est-ce que tu peux poster la ligne 78 ?

Patrice à 10h18

$pdf->Output('Facture.pdf', $_GET['download']?'D':'I');

maliwari à 10h48

Même avec les lignes 237 et 241 c'est la même chose. Initialement tout marchait avec wampserver 2.0.5, j'arrivais à produire ma facture sans soucis ni de bug. Mais, une fois migrer sur 3.0.6 les erreurs ont commencées... Sinon, les productHeaderAddrow(), sont bien définis et s'affiche bien avec l'ancienne version de wampserver et je ne sais pas pourquoi ça ne marche pas avec la version 3.0.6.
Merci

maliwari à 11h05

Il faut ajouter des vérifications. Undefined offset, ça veut dire qu'il ne trouve pas l'index demandé dans l'array. Pour le corriger c'est facile, il faut vérifier si la valeur existe avec isset :
[code]
$pdf->Output('Facture.pdf', isset($_GET['download']) ? 'D':'I');
[/code]
Reste à faire les deux autres lignes de la même manière. Vérifier si la valeur existe avec isset et, si ce n'est pas le cas, choisir une valeur par défaut.

Patrice à 11h42

Merci. Je vais essayer ça tout de suite et vous revenir...
Merci infiniment !

maliwari à 13h48

Salut Patrice,
Je viens de régler le problème de download avec issset, avec tes complications j'ai compris que j'avais fait une erreur au $pdf->totalAdd qui est de dimension deux, et que j'avais mis trois pour pourvoir ajouter la devise, ma seconde valeur vient d'une base de données, maintenant ça marche(la facture s'affiche en pdf)mais pas bien.
J'ai la facture mais j'ai perdu la mise en forme(l'affichage est devenu buzzarre, toutes les données commence en haut de la feuille), probablement à cause des gabarits que mon système ne connaissait pas à travers le intval et $_GET['id']...
Je vais voir claire tête reposé et vous revenir en cas de difficulté

maliwari à 14h28

Salut!
Tout marche Nickel maintenant en mettant les isset où tu as montré...
Tout est parfait, merci infiniment !

maliwari à 20h50

Bonjour, j'essaye d'accéder à votre interface FacturePDF via Javascript (AJAX) mais au retour je n'ai que la sortie imprimante (postscript?) et non le pdf. Le code est ci-dessous. J'ai essaye d'envoyer un header avec "xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");" mais le résultat est le même.
Evidemment index.php fonctionne très bien.
Y aurait-il un moyen ? J'envoie ces factures par mail ensuite.
Merci d'avance.

<html>
<script>
xmlhttp = new XMLHttpRequest();
myUrl="index.php?client="+"NOM DE MON CLIENT";
xmlhttp.open("GET",myUrl,true);
xmlhttp.send();
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
txt2retour=this.responseText;
}
}
</script>
</html>

EchoTango à 23h27

Bonsoir EchoTango,

Je pense que le problème vient de cette ligne :
$pdf->Output('Facture.pdf', $_GET['download'] ? 'D':'I');

La fonction output de FPDF attend trois paramètres de sortie :
1- le chemin
2- le mode
I: envois le PDF vers le navigateur pour affichage ou téléchagement
D: force le chargement du PDF
F: enregistrer le fichier
S: renvoit le document sous forme de string
3- l'encodage

Plus d'info [url]http://www.fpdf.org/en/doc/output.htm[/url]

Il faudrait soit enregistrer le PDF sur le serveur et renvoyer le chemin en retour ou renvoyer le document sous forme de string.

Patrice à 00h01

Merci pour cette réponse. En effet j'ai regardé ces paramètres et ai fait des essais en deux modes 1) exécution directe 2) via JS xmlhttp sachant que mon objectif est bien le mode 2.

En mode 1 le paramètre F crée bien un pdf sur le serveur. Le D crée un pdf local mais m'oblige à valider le répertoire que je ne veux pas faire. Donner le nom du pdf avec répertoire ne change rien. La paramètre S affiche le postscript.

En mode 2, j'arrive parfaitement à créer le pdf sur le serveur paramètre F (donc mon JS appelle le php qui crée le pdf). Le D ne fait rien (ne crée pas le fichier, ne me demande pas de valider le répertoire). Le S c'est pareil : postscript.

Evidemment, je peux télécharger les pdf qui sont créés sur le serveur en local.
Mais maintenant je dois créer mes factures avec fpdf. Ce qui parait évident.

Mon problème c'est que je les crée déjà mes factures avec JS/mysqli. Je peux les imprimer et les mettre à la poste sans problème. Seulement, sur 50 factures mensuelles la moitié est envoyée en pdf par mail.

Et c'est la question, comment créer ces 25 pdf indépendants (donc avec des noms individuels) depuis JS sans intervention manuelle.

Comme un certain l'aurait dit , être ou ne pas être.

Merci.




EchoTango à 20h46

J'ai opté pour la solution suivante :
J'utilise dompdf pour créer la facture en pdf (en utilisant le modèle de facture que j'avais déjà mais sans lui passer donc le html en entier).
Pour les données mysqli, je les passe dans une matrice JSON avec AJAX mode POST, la partie lignes de factures étant évidemment variable d'un client à l'autre.
Ce même php crée le pdf avec un nom de fichier adéquat et l'envoie par mail au client.
Physiquement les factures sont sur le serveur, et je les liste par glob puis les récupère par readfile pour stockage local.
Voilà.
(pour la petite histoire, j'avais déjà écrit cette application il y a 10 ans et qui fonctionne à merveille, facile à mettre à jour et maintenir ..... en EXCEL VBA :-)

EchoTango à 13h47

Super, merci pour le retour :-)

Patrice à 11h04

Bonjour, depuis quelques jours le script ne fonctionne plus du tout pour une raison complètement inconnue ! Pour être sûr que cela ne vienne pas de mon côté j'ai tout de même tout remis par défaut et avec votre exemple, voici l'erreur que j'obtient :

Fatal error: Uncaught Exception: FPDF error: Incorrect unit: Robert Meinard 3 place de Clichy 88154 Nancy le port in /home/pensionaj/www/facture/test/fpdf.php:273 Stack trace: #0 /home/pensionaj/www/facture/test/fpdf.php(127): FPDF->Error('Incorrect unit:...') #1 /home/pensionaj/www/facture/test/index.php(14): FPDF->__construct('K-soul\xC3\xA9 SA\n1 r...', 'Robert Meinard\n...', 'K-soul\xC3\xA9 SA - 1...') #2 {main} thrown in /home/pensionaj/www/facture/test/fpdf.php on line 273

Avez vous une idée d'où cela pourrait venir ? C'est vraiment étrange car j'ai rien touché depuis plusieurs mois et là d'un coup une erreur, vraiment étrange

theobruyere98 à 18h53

Bonsoir theobruyere98,

Étrange.

Quelle version de fpdf ?

À tous hasard, le site est hébergé chez OVH ? J'ai remarqué qu'ils avaient tendances à envoyer les sites vers des serveurs de délestages avec de configurations différentes.

Patrice à 20h01

Bonsoir, merci de votre réponse ! :)

J'utilise une version de 2015 de FPDF car j'avais jamais eu de problème jusqu'à aujourd'hui, j'ai mis à jour FPDF et PHP aujourd'hui et le problème est le même, je suis en effet chez OVH sur un hébergement mutualisé, j'ai testé aussi sur un autre hébergeur d'un ami mais c'est possible que cet autre hébergeur soit aussi OVH je n'ai malheureusement pas l'information ... Je comprends pas trop

theobruyere98 à 00h08

Ajouter votre commentaire

Votre adresse ne sera pas affichée.

Elle sert à vous envoyer une notification.