2012-05-06 5 views
3

J'ai modifié cette question de la pile: Applying watermarks on pdf files when users try to download the files mais j'ai rencontré une erreur, même s'il y avait un commentaire qui disait comment la réparer, ce n'était pas assez élaboré.FPDI/FPDF: filigrane et impression de plusieurs pages

Voici le code:

require_once('fpdf/fpdf.php'); 
require_once('fpdi/fpdi.php'); 

class WaterMark 

{ 
    public $pdf, $file, $newFile, 
     $wmText = "STACKOVERFLOW"; 

/** $file and $newFile have to include the full path. */ 
public function __construct($file, $newFile) 
{ 
    $this->pdf = new FPDI(); 
    $this->file = $file; 
    $this->newFile = $newFile; 
} 

/** $file and $newFile have to include the full path. */ 
public static function applyAndSpit($file, $newFile) 
{ 
    $wm = new WaterMark($file, $newFile); 

    if($wm->isWaterMarked()) 
     return $wm->spitWaterMarked(); 
    else{ 
     $wm->doWaterMark(); 
     return $wm->spitWaterMarked(); 
    } 
} 

/** @todo Make the text nicer and add to all pages */ 
public function doWaterMark() 
{ 
    $currentFile = $this->file; 
    $newFile = $this->newFile; 

    $this->pdf->addPage(); 
    $pagecount = $this->pdf->setSourceFile($currentFile); 

    for($i = 1; $i <= $pagecount; $i++){ 
     $tplidx = $this->pdf->importPage($i); 
     $this->pdf->useTemplate($tplidx, 10, 10, 100); 
     // now write some text above the imported page 
     $this->pdf->SetFont('Arial', 'I', 40); 
     $this->pdf->SetTextColor(255,0,0); 
     $this->pdf->SetXY(25, 135); 
     $this->_rotate(55); 
     $this->pdf->Write(0, $this->wmText); 
    } 

    $this->pdf->Output($newFile, 'F'); 
} 

public function isWaterMarked() 
{ 
    return (file_exists($this->newFile)); 
} 

public function spitWaterMarked() 
{ 
    return readfile($this->newFile); 
} 

protected function _rotate($angle,$x=-1,$y=-1) { 

    if($x==-1) 
     $x=$this->pdf->x; 
    if($y==-1) 
     $y=$this->pdf->y; 
    if($this->pdf->angle!=0) 
     $this->pdf->_out('Q'); 
    $this->pdf->angle=$angle; 

    if($angle!=0){ 
     $angle*=M_PI/180; 
     $c=cos($angle); 
     $s=sin($angle); 
     $cx=$x*$this->pdf->k; 
     $cy=($this->pdf->h-$y)*$this->pdf->k; 

     $this->pdf->_out(sprintf(
      'q %.5f %.5f %.5f %.5f %.2f %.2f cm 1 0 0 1 %.2f %.2f cm', 
      $c,$s,-$s,$c,$cx,$cy,-$cx,-$cy)); 
    } 
    } 

} 
header('Content-type: application/pdf'); 
//header('Content-Disposition: attachment; filename="downloaded.pdf"'); 
WaterMark::applyAndSpit('C:\xampp\htdocs\tst\test0.pdf','C:\xampp\htdocs\tst\output0.pdf'); 

Quand je charge un fichier PDF qui a plus de 2 toutes les pages se fond dans une seule page. J'ai joint l'image dans ce post. enter image description here

Merci.

+0

@vascowhite Une idée sur la façon d'y remédier? –

+0

Pas vraiment, mais je commencerais par vérifier ce qui est en train d'être inséré. Il semble que toute la page ait été tournée. Désolé, mais je n'ai pas beaucoup d'expérience avec fpdf. Je l'ai utilisé, mais seulement pour des choses très basiques. Si j'ai une chance de jouer avec ça plus tard aujourd'hui, je verrai ce que je peux trouver. Bonne chance. – vascowhite

+0

Avez-vous vu cela? http://www.setasign.de/products/pdf-php-solutions/setapdf-stamper/ – vascowhite

Répondre

6

J'ai trouvé quelques erreurs avec ce script. Pour le faire fonctionner changer la méthode doWatermark() à ceci: -

public function doWaterMark() 
{ 
    $currentFile = $this->file; 
    $newFile = $this->newFile; 

    $pagecount = $this->pdf->setSourceFile($currentFile); 

    for($i = 1; $i <= $pagecount; $i++){ 
     $this->pdf->addPage();//<- moved from outside loop 
     $tplidx = $this->pdf->importPage($i); 
     $this->pdf->useTemplate($tplidx, 10, 10, 100); 
     // now write some text above the imported page 
     $this->pdf->SetFont('Arial', 'I', 40); 
     $this->pdf->SetTextColor(255,0,0); 
     $this->pdf->SetXY(25, 135); 
     $this->_rotate(55); 
     $this->pdf->Write(0, $this->wmText); 
     $this->_rotate(0);//<-added 
    } 

    $this->pdf->Output($newFile, 'F'); 
} 

je me suis déplacé la ligne $this->pdf->addPage(); dans la boucle, sinon tout est sortie sur une seule page. J'ai également ajouté $this->_rotate(0); pour redresser le document avant de l'enregistrer. Assez simple vraiment. J'ai commenté les lignes modifiées pour vous.

Je l'ai testé sur un pdf de 32 pages et cela a semblé fonctionner correctement.

+0

Une idée sur la façon de définir la transparence? J'ai changé les valeurs qui sont semblables à ceci mais n'ai eu aucun résultat. http://www.fpdf.org/en/script/script9.php –

+0

Ce n'est pas transparent, juste une couleur pâle et ils ont triché en mettant le filigrane en premier, puis en mettant le texte de la page en plus de cela. http://www.fpdf.org/en/script/watermark.pdf – vascowhite

+0

Ok. Cette astuce ne fonctionnerait pas si le pdf est une copie scannée. –

2

Ce poste m'a beaucoup aidé à démarrer les choses. Mais j'ai rapidement constaté que la FPDF avait quelques pièges que quelques personnes ont vécu. Pour ma part, j'ai également remarqué que le filigrane ne s'affiche que sur la première page dans certaines instances de navigateur, ainsi que sur l'ouverture via Adobe Acrobat (Acrobat X Pro).

Au lieu de cela, je suis passé à l'aide TCPDF, qui a résolu une variété de problèmes, y compris:

  • Pas d'erreur lors de la définition des angles
  • capacité avoir à définir la transparence
  • polices personnalisées
  • Mise à jour Feature: Mise à jour du texte

Pour utiliser les polices personnalisées, il vous suffit de décommenter le bloc de police personnalisé ci-dessous (http://www.tcpdf.org/fonts.php).

En outre, note finale, le package FPDI standard prend uniquement en charge la version PDF 1.4. Donc, si vous importez des PDF qui sont au-dessus, l'importation ne fonctionnera pas et explosera. Vous aurez besoin d'acheter une version commerciale (https://www.setasign.com/products/fpdi-pdf-parser/details/), ou tout simplement enregistrer vos fichiers PDF à la version 1.4, c'est ce que nous avons fait.

Voici mon code mis à jour:

require_once(APPPATH . 'third_party/tcpdf/tcpdf.php'); 
require_once(APPPATH . 'third_party/fpdi/fpdi.php'); 

class WatermarkerTCPDF extends FPDI { 
    public $pdf, $file, $newFile, 
      $wmText = "STACKOVERFLOW", 
      $fontsize = 24, 
      $fontfamily = 'ptsansnarrow400'; 

    /** $file and $newFile have to include the full path. */ 
    public function __construct($file = null, $newFile = null) { 
     $this->pdf = new FPDI(); 
     //custom fonts 
     //$this->fontfamily = $this->pdf->addTTFfont(APPPATH . 'third_party/tcpdf/ttf/ptsansnarrow400.ttf', 'TrueTypeUnicode', ''); 
     if (!empty($file)) { 
      $this->file = $file; 
     } 
     if (!empty($newFile)) { 
      $this->newFile = $newFile; 
     } 
    } 

    /** $file and $newFile have to include the full path. */ 
    public static function applyAndSpit($file, $newFile = null) { 
     $wm = new Watermarker($file, $newFile); 

     if ($wm->isWaterMarked()) 
      return $wm->spitWaterMarked(); 
     else { 
      $wm->doWaterMark(); 
      return $wm->spitWaterMarked(); 
     } 
    } 

    /** @todo Make the text nicer and add to all pages */ 
    public function doWaterMark() { 
     $currentFile = $this->file; 
     $newFile = $this->newFile; 

     $pagecount = $this->pdf->setSourceFile($currentFile); 

     for ($i = 1; $i <= $pagecount; $i++) { 
      $tplidx = $this->pdf->importPage($i); 
      $specs = $this->pdf->getTemplateSize($tplidx); 
      $this->pdf->SetPrintHeader(false); 
      $this->pdf->SetPrintFooter(false); 
      $this->pdf->addPage($specs['h'] > $specs['w'] ? 'P' : 'L'); 
      $this->pdf->useTemplate($tplidx, null, null, 0, 0, true); 

      // now write some text above the imported page 
      $this->pdf->SetFont($this->fontfamily, '', $this->fontsize); 
      $this->pdf->SetTextColor(204, 204, 204); 
      //$this->pdf->SetXY($specs['w']/2, $specs['h']/2); 
      $_x = ($specs['w']/2) - ($this->pdf->GetStringWidth($this->wmText, $this->fontfamily, '', $this->fontsize)/2.8); 
      $_y = $specs['h']/2; 
      $this->pdf->SetXY($_x, $_y); 
      //$this->pdf->SetXY(0, 0); 
      $this->pdf->setAlpha(0.3); 
      $this->_rotate(45, 100, 100); 
      $this->pdf->Write(0, $this->wmText); 
      //$this->pdf->writeHTMLCell($w=0, $h=0, $x='', $y='', $this->wmText, $border=0, $ln=1, $fill=0, $reseth=true, $align='', $autopadding=true); 
     } 

     if (empty($newFile)) { 
      header('Content-Type: application/pdf'); 
      $this->pdf->Output(); 
     } else { 
      $this->pdf->Output($newFile, 'F'); 
     } 
    } 

    public function isWaterMarked() { 
     //return (file_exists($this->newFile)); 
     $_file = $this->newFile; 
     $file = file_get_contents($_file); 
     force_download($file); 
    } 

    public function spitWaterMarked() { 
     $_file = $this->newFile; 
     $file = file_get_contents($_file); 
     force_download($file); 
     //return readfile($this->newFile); 
    } 

    protected function _rotate($angle, $x = -1, $y = -1) { 
     if ($x == -1) 
      $x = $this->pdf->x; 
     if ($y == -1) 
      $y = $this->pdf->y; 
     //if ($this->pdf->angle != 0) 
      //$this->pdf->_out('Q'); 
     $this->pdf->angle = $angle; 

     if ($angle != 0) { 
      $angle*=M_PI/180; 
      $c = cos($angle); 
      $s = sin($angle); 
      $cx = $x * $this->pdf->k; 
      $cy = ($this->pdf->h - $y) * $this->pdf->k; 

      $this->pdf->_out(sprintf(
          'q %.5f %.5f %.5f %.5f %.2f %.2f cm 1 0 0 1 %.2f %.2f cm', $c, $s, -$s, $c, $cx, $cy, -$cx, -$cy)); 
     } 
    } 

    public function wmText($text = null) 
    { 
     $total = 20; 
     if (!empty($text)) { 
      $this->wmText = ''; 
      for ($i = 0; $i < $total; $i++) { 
       $this->wmText .= ' ' . $text; 
      } 

     } 

     return $this; 
    } 
} 

Pour utiliser cela, il suffit:

try { 
    //this is for CodeIgniter 
    $this->load->library('WatermarkerTCPDF'); 

    //if your using it as a standard class in vanilla PHP just do: 
    //require_once('PATH_TO_LIBRARY/WatermarkerPDF.php'); 

    //If you want to output the PDF to another file, you can supply 
    //a second parameter: new WatermarkerTCPDF($file_path, $new_file_path); 
    //just remember, the full path is required 
    $watermark = new WatermarkerTCPDF($file_path); 
    $watermark->wmText($this->session->userdata('email')); 
    $watermark->doWaterMark(); 
} catch (Exception $e) { 
    exit($e->getMessage()); 
} 

Quoi qu'il en soit, espérons que cela va aider quelqu'un jour!

+0

A m'a aidé. Tu es un sauveur! –

+0

m'a aidé. Tu es un sauveur! ² =) –

Questions connexes