123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160 |
- <?php
- /**
- Classe de génération des PDF à partir d'un flux html.
- Fonctionne sous linux et windows, necessite les binaires wkhtml placés dans "erp\lib\wkhtmltopdf"
-
- Sous linux :
- sudo apt-get install wkhtmltopdf
- sudo chmod a+x /usr/local/bin/wkhtmltopdf
- sudo apt-get install openssl build-essential xorg libssl-dev
- sudo apt-get install xvfb
- echo xvfb-run -a -s "-screen 0 640x480x16" wkhtmltopdf "$@" > /usr/local/bin/wkhtmltopdf.sh
- sudo chmod a+x /usr/local/bin/wkhtmltopdf.sh
- ex utilisation :
- $pdf = new Pdf('<h1>Hello World</h1>');
- $pdf->orientation = 'Landscape';
- header('Content-Type: application/pdf');
- header('Content-Disposition: attachment; filename="my.pdf"');
- echo $pdf->generate();
- Pour ajouter un header, il faut ajouter les éléments suivants :
- <!-- #header --> avant le contenu du header
- <!-- /header --> après le contenu du header
-
- De même avec le footer (remplacer header par footer)
-
- @author v.carruesco, v.morreel
- @version 2.0
- **/
- class Pdf{
- public $html,$orientation,$margin,$css;
- function __construct($html = null, $margin = array(), $format = 'A4', $orientation = 'Portrait'){
- $this->html = $html;
- $this->margin = (object) array(
- 'top' => isset($margin['top']) ? $margin['top'] : '10',
- 'right' => isset($margin['right']) ? $margin['right'] : '10',
- 'bottom' => isset($margin['bottom']) ? $margin['bottom'] : '10',
- 'left' => isset($margin['left']) ? $margin['left'] : '10'
- );
- $this->format = $format;
- $this->orientation = $orientation;
- }
- // Retourne (uniquement sur les pdf avec texte editable) la liste des champs editable
- // du pdf spécifié et leurs valeurs. Si le parametre onlyfdf est a true, la méthode retournera
- // le format fdf brut (utile uniquement pour du débug ou pour de l'interne)
- // NB : Penser a installer ``apt-get install pdftk`` (ou pdftk pour windows) sur le système avant de lancer ce script
- public static function extractData($file,$onlyfdf = false){
- $data = dirname($file).DIRECTORY_SEPARATOR.'data.fdf';
- $command = 'pdftk '.$file.' generate_fdf output -';
- $datastream = shell_exec($command);
- if($onlyfdf) return $datastream;
- preg_match_all('|\/V ([^\n]*)\n\/T \(([^\n]*)\)|iUsm', $datastream, $matches,PREG_SET_ORDER);
- $parameters = array();
- foreach ($matches as $match) {
- if(count($match)==3)
- $parameters[$match[2]] = $match[1];
- }
- return $parameters;
- }
- // Utilise le pdf $file comme modèle (uniquement un pdf avec texte editable) et le remplis avec le tableau clé valeur $parameters
- // puis retourne le flux du pdf remplis.
- // Mettre la valeur /Yes pour les checkbox cochées ou / pour les décochées
- // L'argument $flat, définit si le document final doit être a plat ou encore editable
- // NB : Penser a installer ``apt-get install pdftk`` (ou pdftk pour windows) sur le système avant de lancer ce script
- public static function fillData($file,$parameters,$flat = false){
- $fdf = self::extractData($file,true);
- $fdf = preg_replace_callback('|\/V ([^\n]*)\n\/T \(([^\n]*)\)|ism',function($m) use ($parameters){
- $return = '/V ';
- $value = isset($parameters[$m[2]]) ? $parameters[$m[2]]: '';
- if($value=='/'){
- $return .= $value;
- }else{
- $return .= '('.$value.')';
- }
- $return .= PHP_EOL;
- $return .= '/T ('.$m[2].')';
- return $return;
- },$fdf);
- $command = 'echo "'.str_replace('"','\"',$fdf).'"| pdftk '.$file.' fill_form - output -';
- if($flat) $command.=' flatten';
- $datastream = shell_exec($command);
- return $datastream;
- }
- public function generate(){
- $fileName = time().mt_rand(0,100);
- if(!file_exists(File::dir().'tmp')) mkdir(File::dir().'tmp');
- $bodyPath = File::dir().'tmp'.SLASH.$fileName.'.html';
- $pdfPath = File::dir().'tmp'.SLASH.$fileName.'.pdf';
- $body = $this->html;
- $head = '';
- $foot = '';
- //Récupération du head html
- if(preg_match("/<!DOCTYPE.*<body.*>/isU", $body, $match))
- $head = $match[0];
- //Récupération du footer html
- if(preg_match("/<\/body>.*<\/html>/isU", $body, $match))
- $foot = $match[0];
- //Récupération du header pdf
- if(preg_match("/<!--[\s\t\r\n]*#header[\s\t\r\n]*-->(.*)<!--[\s\t\r\n]*\/header[\s\t\r\n]*-->/isU", $body, $match))
- $header = $match[0];
- //Récupération du footer pdf
- if(preg_match("/<!--[\s\t\r\n]*#footer[\s\t\r\n]*-->(.*)<!--[\s\t\r\n]*\/footer[\s\t\r\n]*-->/isU", $body, $match))
- $footer = $match[0];
- //Récupération du body
- if(isset($header)){
- $body = str_replace($header, '', $body);
- $header = $head.$header.$foot;
- }
- if(isset($footer)){
- $body = str_replace($footer, '', $body);
- $footer = $head.$footer.$foot;
- }
- file_put_contents($bodyPath, $body);
- $outcmd = array();
- $cmd = strtoupper(substr(PHP_OS, 0, 3)) === 'WIN' ? '"C:'.SLASH.'Program Files'.SLASH.'wkhtmltopdf'.SLASH.'bin'.SLASH.'wkhtmltopdf.exe" ' : "/usr/local/bin/wkhtmltopdf.sh ";
- $cmd .= '-s '.$this->format.' -O '.$this->orientation.' -T '.$this->margin->top.' -R '.$this->margin->right.' -B '.$this->margin->bottom.' -L '.$this->margin->left;
- $cmd .= ' -d 100 --print-media-type ';
- $cmd .= ' --user-style-sheet '.dirname(__FILE__).'/../'.$this->css.' --enable-javascript --javascript-delay 1000 ';
-
- if(isset($header)) {
- $headerPath = File::dir().'tmp'.SLASH.'header-'.$fileName.'.html';
- file_put_contents($headerPath, $header);
- $cmd .= ' --header-html '.$headerPath.' --header-spacing 5 --margin-top 40';
- }
- if(isset($footer)) {
- $footerPath = File::dir().'tmp'.SLASH.'footer-'.$fileName.'.html';
- file_put_contents($footerPath, $footer);
- $cmd .= ' --footer-html '.$footerPath.' --footer-spacing 5 --margin-bottom 30';
- }
- $cmd .= ' --footer-right "[page] / [toPage]" --footer-font-size 8 ';
- $cmd .= $bodyPath.' '.$pdfPath;
- exec($cmd, $outcmd);
- $stream = file_get_contents($pdfPath);
- if(isset($header)) unlink($headerPath);
- if(isset($footer)) unlink($footerPath);
- unlink($bodyPath);
- unlink($pdfPath);
- return $stream;
- }
- }
- ?>
|