/usr/local/bin/wkhtmltopdf.sh
sudo chmod a+x /usr/local/bin/wkhtmltopdf.sh
ex utilisation :
$pdf = new Pdf('
Hello World
');
$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 :
avant le contenu du 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){
$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 -';
$fdfPath = File::temp().rand(0,10000).'fdf';
$pdfPath = File::temp().rand(0,10000).'pdf';
file_put_contents($fdfPath, $fdf);
$command = 'pdftk '.$file.' fill_form '.$fdfPath.' output "'.$pdfPath.'"';
if($flat) $command.=' flatten';
shell_exec($command);
$datastream = file_get_contents($pdfPath);
unlink($pdfPath);
unlink($fdfPath);
return $datastream;
}
/*
Convertis le tableau de chemin d'images fournis en un PDF
Prérequis systeme :
- Installer le paquet imagemagick (apt-get install imagemagick)
nb: Si le pb "convert-im6.q16: not authorized `outfile.pdf' @ error/constitute.c/WriteImage/1037" apparait
editer /etc/ImageMagick-6/policy.xml et changer sur la ligne "" PDF le droit none à read|write .*/
public static function fromImage($images,$pdfPath){
return Image::toPdf($images,$pdfPath);
}
public function generate($alt = false){
$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 = '';
if($alt) {
//Récupération des actions URL html
if(preg_match_all("/url\((\'|\")(.*)(\"|\')/U", $body, $match)) {
$urls = $match[2];
foreach ($urls as $key => $url) {
if (preg_match("/asset=(.*.woff(2?))/i", $url, $asset)) {
$path = get_asset_absolute_path($asset[1]);
$body = str_replace($url, $path, $body);
}
}
}
}
//Récupération du head html
if(preg_match("//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("/(.*)/isU", $body, $match))
$header = $match[0];
//Récupération du footer pdf
if(preg_match("/(.*)/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 = get_OS() === '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';
}
if(isset($footer)) {
$footerPath = File::dir().'tmp'.SLASH.'footer-'.$fileName.'.html';
file_put_contents($footerPath, $footer);
$cmd .= ' --footer-html '.$footerPath.' --footer-spacing 5';
}
$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;
}
}
?>