Link to home
Start Free TrialLog in
Avatar of Chris Ryan
Chris RyanFlag for United Kingdom of Great Britain and Northern Ireland

asked on

PDF converter for a PHP LAMP environment

Hi,

We are creating a final Assessment page in Limesurvey (for those who know Limesurvey). It's a LAMP environment.

I had originally thought that we needed a PHP HTML to PDF converter, but reading through the various historical posts there appear to be too many problems with this approach, and what we really need is a converter for our core data model which is PHP based.  However most of the posts are several years old and I wonder if the world has moved on since then?

I believe therefore that we want to source a converter to be able create a PDF document with the following features:

Independent of Browser - Does not depend on the Web Browser
Full CSS support
Auto/Manual paging
Text and Links preservered (not a screenshot)
Handles nested tables

It would be nice if it has a (switchable) JS engine built in, but this is not a prerequisite.

Free (GPL 2) source would be good but happy to pay a reasonable price (up to a few hundred bucks) if we get the right features set out of the box, but not thousands of dollars, and definitely not on a per page pricing model.

Any tips, hints or corrections would also be greatly appreciated :)

Many thanks
Chris
Avatar of Dan Craciun
Dan Craciun
Flag of Romania image

Try Apache FOP. Browser independent and free.

https://xmlgraphics.apache.org/fop/

HTH,
Dan
PDFLib -> payment but powerful

fpdf -> free and works good. Look in the site for community libraries and functions: there should be at least one to convert from HTML to PDF. (To don't reinvent the wheel...)

Hope this helps.
ASKER CERTIFIED SOLUTION
Avatar of Ray Paseur
Ray Paseur
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
I've had the best results with Prince @ http://www.princexml.com

I came across this source the other day:

require('prince.php');
ob_start();
include('report.php');
$dir = dirname(__FILE__);
$out = str_replace('folder/', "$dir/folder/", ob_get_clean());
$out = str_replace('\\', '/', $out);
$style = '	@page {
		margin: 50pt 20pt 40pt 20pt ;
		prince-shrink-to-fit: auto;
	}
	body{background-color:#fff}';
$out = str_replace('body{background-color:#fff}', $style, $out);

if (preg_match('/(qr\.php\?txt=)(.*)(") /i', $out, $regs)) $out = str_replace($regs[0], "$dir\\reports\\$dest.png\" ", $out);

$prince = new Prince('/www/bin/prince/bin/prince.exe');
$prince->setHTML(true);
#$prince->setJavaScript(true);
#$prince->setLog("$dir\\prince.log");
$filename = $dir . "\\reports\\$dest.pdf";
$prince->convert_string_to_file($out, $filename, $var);

// patch watermark
$file = file_get_contents($filename);
$pattern = array(
	'%/Producer \(Prince \d+[.]?\d+( rev \d+)? \\\\\(www\.princexml\.com\\\\\)\).%si',
	'%(<</Type /Annot).(/Rect \[572\.0000 752\.0000 597\.0000 777\.0000\]).(/Border \[0 0 0\]).(/AP <</N \d+ \d+ R>>).(/BS <</Type /Border).(/W 2).(/S /S>>).(/Subtype /Text).(/T \(www\.princexml\.com\)).(/Subj \(Prince - Non-commercial License\)).(/Contents \(This document was created with Prince, a great way of getting web content onto paper\.\)).(/Popup \d+ \d+ R).(/Name /Note>>).%si',
	'<</Type /Annot
/Rect [370.6650 296.4787 482.8567 307.3713]
/Border [0 0 0]
/Subtype /Link
/A <</Type /Action
/S /URI
/URI (https://www.example.com/)>>>>
');
if (preg_match($pattern[0], $file)) {
	$file = preg_replace($pattern[0], '', $file);
}
if (preg_match($pattern[1], $file)) {
	$file = preg_replace($pattern[1], $pattern[2], $file);
}
file_put_contents($filename, $file);

header('Pragma: public');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Cache-Control: private', false);
header('Content-type: application/pdf');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s', filemtime($filename)) . ' GMT');
header("Content-Disposition: $mode; filename=\"$dest.pdf\"");
header('Content-Transfer-Encoding: binary');
header('Content-Length: ' . filesize($filename));
header('Accept-Ranges: bytes');
header('Connection: close');
@readfile($filename);
exit;

Open in new window


Though I don't think $3800 for one license meets your qualifications.  :-)
Avatar of Chris Ryan

ASKER

Hi Ray,

Thanks for your sage advice.  Obviously the voice of experience here :)  and thanks so much for the example code.  I take it that nested tables and keeping links is no problem with either of the suggested solutions?

Hi x66_x72_x65_x65,

Thanks so much for taking the time to provide the Prince solution.  Unfortunately this breaks my price barrier, costing about $4,000 for a single server solution (and we would need two servers for back up).

Thanks also to everyone else for their contribution

Kind regards
Chris
@Chris_Ryan, I agree.  There is some valuable info the glean form the source, however.  I've found the following method particularly useful in rendering css:

ob_start();
include('source.php');
$out = str_replace('folder/', "$dir/folder/", ob_get_clean());
$out = str_replace('\\', '/', $out);

Open in new window


etc.
Thanks for the points.  Links are no problem.  The whole idea of "nested tables" goes away in PDF layout.  Tables are an artifact of HTML-think, and with PDF you get to place the data exactly where you want it on the page with X/Y coordinates.  Good luck with it, ~Ray