PDA

View Full Version : A PHP Class for html2ps (html to pdf 100% server side)


Jak-S
11-20-2005, 06:11 AM
Sorry if this is considered a double post, but since the forum was moved around my old post has disappeared, and I still thing this might be useful to some people, as the programming API isnÃÃâ€*’Ãâ€Â*â€â⠀žÂ¢ÃƒÆ’ƒâ€šÃ‚¢Ã ƒÆ’Ãâ€*բ̈ ƒâ€šÃ‚¢ÃƒÂ¢Ã¢â‚¬Å¡Ã‚¬Ã†¦Ãƒâ€šÃ‚¡ÃƒÆ’‚ ¬ÃƒÃâ€*’¢Ã ƒÂ¢Ã¢â€šÂ¬Ã …¾Ã‚Ã ¡Ãƒâ€šÃ‚¢t available yet.

Hi,

Before I go into detail, I want to say that I know there is going to be a programming API for html2ps, it will be much better than this code, and will make this code useless. However I am currently in a situation where I need to use html2ps server side, and I have a deadline (of next week) so I wrote this.

You can basically use this PHP class server side to send html2ps a string of html, rather than the URL of a page, it will then take that string, do all the processing, and either save the file on the server, or send it to the client (browser) requesting the php page that calls the class.

I know this could have been done better (without having to make a new http request on the server), by making changes to the html2ps source, however I took one look at it and got scared, so IÃÃâ€*’Ãâ€Â*â€â„ ¢ÃƒÆ’‚¢Ã Æ’Ãâ€*’¢ÃÃ⠀šÃ‚¢ÃƒÂ¢Ã¢â‚¬Å¡Ã‚¬Ã…à ƒâ€šÃ‚¡ÃƒÆ’‚ ¬ÃƒÆ’Ãâ€*բ̮ ’¢â‚¬Ãâ €¦Ã‚¾Ãƒâ€šÃ‚à ƒâ€šÃ‚¢ve deliberately written it so that the html2ps source doesnÃÃâ€*’Ãâ€Â*â€à ¢â€žÂ¢ÃƒÆ’ƒâ€šÃ‚¢ ÃÃâ€*’¢ÃƆ™Ãƒâ€šÃ‚¢ÃƒÂ¢Ã¢â‚¬Å¡Ã‚¬Ãâ₠¬Â¦Ãƒâ€šÃ‚¡ÃƒÆ’‚ÂÃ⠀šÃ‚¬ÃƒÆ’Ãâ€*’¢Ã ƒÆ’¢â‚¬Ã ƒâ€¦Ã‚¾Ãƒâ€šÃâ₠¬Å¡Ãƒâ€šÃ‚¢t need to edited in any way.

IÃÃâ€*’Ãâ€Â*â€â„ ¢ÃƒÆ’‚¢Ã Æ’Ãâ€*’¢ÃÃ⠀šÃ‚¢ÃƒÂ¢Ã¢â‚¬Å¡Ã‚¬Ã…à ƒâ€šÃ‚¡ÃƒÆ’‚ ¬ÃƒÆ’Ãâ€*բ̮ ’¢â‚¬Ãâ €¦Ã‚¾Ãƒâ€šÃ‚à ƒâ€šÃ‚¢ve commented it up best I can, so I hope it all makes sense, I donÃÃâ€*’Ãâ€Â*â€â⠀žÂ¢ÃƒÆ’ƒâ€šÃ‚¢Ã ƒÆ’Ãâ€*բ̈ ƒâ€šÃ‚¢ÃƒÂ¢Ã¢â‚¬Å¡Ã‚¬Ã†¦Ãƒâ€šÃ‚¡ÃƒÆ’‚ ¬ÃƒÃâ€*’¢Ã ƒÂ¢Ã¢â€šÂ¬Ã …¾Ã‚Ã ¡Ãƒâ€šÃ‚¢t think the way the paths work is particularly good, it would be nice if they could all be relative, but I donÃÃâ€*’Ãâ€Â*â€â⠀žÂ¢ÃƒÆ’ƒâ€šÃ‚¢Ã ƒÆ’Ãâ€*բ̈ ƒâ€šÃ‚¢ÃƒÂ¢Ã¢â‚¬Å¡Ã‚¬Ã†¦Ãƒâ€šÃ‚¡ÃƒÆ’‚ ¬ÃƒÃâ€*’¢Ã ƒÂ¢Ã¢â€šÂ¬Ã …¾Ã‚Ã ¡Ãƒâ€šÃ‚¢t know how to do it, anyway, it works ok for my needs. If anyone wants to suggest any changes/improvements then that would be great.

Cheers,

Jack

P.S. The site root folder does not have to be the same folder your domain name points to, it can be any number of folders down from that. Otherwise working out the absolute paths to the other folders would have been much easier.


<?php

class html2pdf {

var $atts;

var $siteRoot;
var $html2psPath;
var $tempPath;
var $outputPath;

var $output = 'client';

function html2pdf() {

$this->atts['pixels'] = 1024;
$this->atts['scalepoints'] = true;
$this->atts['renderimages'] = true;
$this->atts['renderlinks'] = true;
$this->atts['media'] = 'A4';
$this->atts['cssmedia'] = 'screen';
$this->atts['leftmargin'] = 10;
$this->atts['rightmargin'] = 10;
$this->atts['topmargin'] = 10;
$this->atts['bottommargin'] = 10;
$this->atts['landscape'] = false;
$this->atts['pageborder'] = false;
$this->atts['debugbox'] = false;
$this->atts['encoding'] = NULL;
$this->atts['method'] = 'fpdf';
$this->atts['pdfversion'] = 1.3;
$this->atts['compress'] = true;
$this->atts['transparency_workaround'] = false;
$this->atts['imagequality_workaround'] = false;

$this->siteRoot = '../'; // relative path from the page calling this class to the root of your site
$this->html2psPath = 'html2ps/'; // relative path from the root of your site to the folder that contains html2ps.php
$this->tempPath = 'temp/'; // relative path from the root of your site to the folder where the html string temporarily saved
$this->outputPath = 'output/'; // relative path from the root of your site to the folder where the pdf will be saved
$this->outputFile = 'mypdf'; // pdf file name

}

function createPDF($data) {

// all the code from here to the next comment basically take the
// siteRoot root relative path, and the absolute script path from
// the SCRIPT_NAME enviroment variable, and work out what the absolute
// path to the root of the site should be

$hostName = $_SERVER['SERVER_NAME'];

$scriptPath = getenv('SCRIPT_NAME');
$scriptPath = dirname($scriptPath);
$scriptPath = explode('/', $scriptPath);
$levelsUp = substr_count($this->siteRoot, '../');

$newPath = NULL;
foreach($scriptPath as $key => $value) {
if($key < count($scriptPath) - $levelsUp) {
$newPath .= $value.'/';
}
}

// these are the paths used in the script:
$scr2fnc = $this->siteRoot.$this->html2psPath; // relative: the script calling this class to the html2ps folder
$scr2tmp = $this->siteRoot.$this->tempPath; // relative: the script calling this class to the temp folder
$scr2out = $this->siteRoot.$this->outputPath; // relative: the script calling this class to the output folder
$rem2tmp = 'http://'.$hostName.$newPath.$this->tempPath; // absolute: the remote path to the temp folder *
$rem2fnc = 'http://'.$hostName.$newPath.$this->html2psPath; // absolute: the remote path to the html2ps folder **

// * this is because i dont know how to work out the relative path
// from the page calling this class to the html2ps folder, and
// because html2ps automatically sticks http:// at the begining of
// the url if it dosent have it already, so relative paths dont work

// ** this is because you cant use a relative path in file_get_contents,
// if you do, php will read the file server side, and not actually
// send the http request to it


// write the data to a file, because html2ps will only read a remote
// file, you cant send it a string
$file = fopen($scr2tmp.'temp.html', 'w');
fwrite($file, $data);
fclose($file);

// check the request attributes
foreach($this->atts as $key => $value) {

if(is_bool($value) && $value == true) {
$this->atts[$key] = 1;
}
if(is_bool($value) && $value == false) {
unset($this->atts[$key]);
}
else if(is_null($value)) {
$this->atts[$key] = '';
}

}

// create the request url
$this->atts['URL'] = $rem2tmp.'temp.html';
$urlString = http_build_query($this->atts);
$url = $rem2fnc.'html2ps.php?'.$urlString;

// request the pdf
switch ($this->output) {

case 'client':
$url .= '&output=0';
header("Content-type: application/pdf");
echo file_get_contents($url);
break;

case 'server':
$url .= '&output=1';
$output = file_get_contents($url);
$pdf = fopen($scr2out.$this->outputFile.'.pdf', 'w');
fwrite($pdf, $output);
fclose($pdf);
break;

}

// delete the tempoary file
unlink($scr2tmp.'temp.html');

}

}

/*------------------------------------------------------------*/
/*------------------------------------------------------------*/

$data = file_get_contents('sample.html'); // this would be your string that contains the html

$pdf = new html2pdf;
$pdf->createPDF($data);

?>

rapha
12-06-2005, 01:17 PM
Hi All!

First off, thanks a lot for this great piece of software, and also thanks to Jack for his class. I was looking for something like it, but it didn't quite fit. So, reading his class I made my own. It's not as featured as his but the handling of paths is a lot different.

Maybe it can be as useful to somebody else as html2ps was for me.
Comments and suggestions of course more than welcome! :-)

Usage is more than simple (example):$pdf = new PDF($html_string_you_want_converted);
echo '<a href="'.$pdf->getURL().'">Download PDF</a>';Best regards,
Raphael

---< snip >---
/* Not present in PHP5? */
if(!function_exists('http_build_query')) {
function http_build_query( $formdata, $numeric_prefix = null, $key = null ) {
$res = array();

foreach ((array)$formdata as $k=>$v) {
$tmp_key = urlencode(is_int($k) ? $numeric_prefix.$k : $k);
if ($key) {
$tmp_key = $key.'['.$tmp_key.']';
}
if ( is_array($v) || is_object($v) ) {
$res[] = http_build_query($v, null, $tmp_key);
} else {
$res[] = $tmp_key."=".urlencode($v);
}
}

return implode("&", $res);
}
}

class PDF {
var $_url;
var $_tmp_path;
var $_html_file;
var $_html_url;
var $_html2ps_url;
var $_pdf_data;

function PDF($html, $html2ps_options = NULL, $tmp_path = NULL, $html2ps_path = NULL)
{
$this->url = 'http://'.$_SERVER['SERVER_NAME'].dirname($_SERVER['REQUEST_URI']);

if ($tmp_path) $this->tmp_path = $tmp_path;
else $this->tmp_path = 'tmp';

if (!$html2ps_options) {
$html2ps_options['pixels'] = 1024;
$html2ps_options['scalepoints'] = true;
$html2ps_options['renderimages'] = true;
$html2ps_options['renderlinks'] = true;
$html2ps_options['media'] = 'A4';
$html2ps_options['cssmedia'] = 'screen';
$html2ps_options['leftmargin'] = 10;
$html2ps_options['rightmargin'] = 10;
$html2ps_options['topmargin'] = 10;
$html2ps_options['bottommargin'] = 10;
$html2ps_options['landscape'] = false;
$html2ps_options['pageborder'] = false;
$html2ps_options['debugbox'] = false;
$html2ps_options['encoding'] = NULL;
$html2ps_options['method'] = 'fpdf';
$html2ps_options['pdfversion'] = 1.3;
$html2ps_options['compress'] = true;
$html2ps_options['transparency_workaround'] = false;
$html2ps_options['imagequality_workaround'] = false;
$html2ps_options['URL'] = $this->url.'/'.$this->tmp_path.'/'.session_id().'.html';
}

foreach ($html2ps_options as $key => $value) {
if (is_bool($value)) {
if ($value) {
$html2ps_options[$key] = 1;
} else {
unset($html2ps_options[$key]);
}
}
}

if ($html2ps_path) $this->html2ps_url = $html2ps_path;
else $this->html2ps_url = 'php/html2ps';
$this->html2ps_url = $this->url.'/'.$this->html2ps_url.'/html2ps.php?';
$this->html2ps_url .= http_build_query($html2ps_options);

$html_file = fopen($this->tmp_path.'/'.session_id().'.html', 'w');
fwrite ($html_file, $html);
fclose ($html_file);
$this->html_file = $this->tmp_path.'/'.session_id().'.html';
}

function createPDF()
{
$this->pdf_data = file_get_contents($this->html2ps_url.'&output=1');
unlink($this->html_file);

$pdf_file = fopen($this->tmp_path.'/'.session_id().'.pdf', 'w');
fwrite($pdf_file, $this->pdf_data);
fclose($pdf_file);
}

function getURL()
{
if (! $this->pdf_data) $this->createPDF();
return $this->url.'/'.$this->tmp_path.'/'.session_id().'.pdf';
}
}---< snap >---