PDF Generation with Apache FOP
I wrote a small PHP class for generation of PDF document using XML,XSL-FO and Apache FOP Generation.
Here is a process outline:
- Install Apache FOP on your server;
- Edit the relevant path to the executible in the declaration part of the class;
- Create XML string;
- Create XSL file to convert the XML string to XSL-FO;
- Create instance of XMLPDFGeneration class
- Set debug flag, fo file output directory and pdf file output directory
- Call XMLPDFExecute() function;
- You are done - the PDF file is generated;
Here is the code:
<?
class XMLPDFGeneration{
private $fop_command="/usr/local/src/apache_fop/fop-0.20.5/fop.sh";
private $debug_pdf = TRUE;
private $debug_file="/var/www/documents/pdfgen/pdfcall.txt";
private $fo_file_prefix="FO_";
private $fo_output_dir="/tmp";
private $pdf_file_prefix="CA_";
private $pdf_output_dir="/var/www/documents/pdfgen/";
private $error_redirect_uri="http://www.google.com";
function __construct(){
}
function SetXMLString($xml_string){
$this->xml_string=$xml_string;
}
function SetXSLTFile($xslt_file){
$this->xslt_file=$xslt_file;
}
function GetXSLTFile(){
return $this->xslt_file;
}
function SetPDFOutputDirectory($pdf_output_dir){
$this->pdf_output_dir=$pdf_output_dir;
}
function SetPDFFilePrefix($pdf_file_prefix){
$this->pdf_file_prefix=$pdf_file_prefix;
}
function SetFOFilePrefix($fo_file_prefix){
$this->fo_file_prefix=$fo_file_prefix;
}
function SetPDFDebug($bool_debug_pdf){
$this->debug_pdf=$debug_pdf;
}
function SetPDFDebugFile($debug_file){
$this->debug_file=$debug_file;
}
function SetErrorRedirectURI($error_redirect_uri){
$this->error_redirect_uri=$error_redirect_uri;
}
function SetFOPCommand($fop_command){
$this->fop_command=$fop_command;
}
function XMLPDFExecute(){
// create temporary file
$fo_file=$this->CreateTempFOFile();
// chek if file created
if(strlen($fo_file) > 0){
// perform XSLT transformation to generate fo file
$xsl_transformation=$this->XML2XSLFOTransformation($fo_file);
// check for successful XSLT transformation
if ($xsl_transformation != "0"){
// assign output pdf file location and file prefix
$output_file = tempnam($this->pdf_output_dir, $this->pdf_file_prefix);
// build command string
$command_string=$this->fop_command . " ".$fo_file." ".$output_file;
// if in debug mode print some debugging info into a file
if($this->debug_pdf){ $command_string.=" >> ".$this->debug_file; }
// record in error log
if($this->debug_pdf){ error_log("About to exec: '" . $command_string . "'"); }
// unlink($_SERVER['DOCUMENT_ROOT']."pdfgen/" . $tmpfile);
// perform fo to pdf conversion; Save the result of the conversion in variable for later use
$execresult = exec($command_string, $output_string, $result);
// record in error log
if($this->debug_pdf){ error_log("Fop Execution Result: '" . print_r($result) . "'"); }
// rename output file name to have pdf extension
$realoutput = $output_file.".pdf";
$mv_result=exec("mv ".$output_file." ".$realoutput, $output_string, $rename_res);
$output_file = $realoutput;
// record in error log
if($this->debug_pdf){
error_log("Rename Result: '" . $rename_res . "'");
error_log("New Output File Name: '" . $output_file . "'");
}
// check if file created and written successfully
if (file_exists($output_file)) {
// strip the /var/www/ from the output file name
$output_url=substr($output_file, 8);
// record in error log
if($this->debug_pdf){ error_log("Output URL: '" . $output_url . "' ".$output_file); }
// redirect to the output file location
header("Location: ".$output_url);
// the file was not created successfully
}else{
// record in error log
if($this->debug_pdf){ error_log("PDF Output file not found ($output_file)"); }
header("Location: ".$this->error_redirect_uri);
}
// the xslt transformation not sucessful
}else{
// record in error log
if($this->debug_pdf){
error_log("XSLT transformation not sucessful'". $xsl_transformation ."'");
}
header("Location: ".$this->error_redirect_uri);
return 0;
}
// fo file not created
}else{
// record in error log
if($this->debug_pdf){ error_log("FO file not created '". $xsl_transformation ."'"); }
header("Location: ".$this->error_redirect_uri);
return 0;
}
// return to the calling function
return 1;
} // end of function
function CreateTempFOFile(){
// assign output fo file location and fo file prefix
$fo_file = tempnam($this->fo_output_dir, $this->fo_file_prefix);
if($this->debug_pdf){
error_log("FO file name and location: '" . $fo_file . "'");
error_log("Does the FO file exists: '" . is_file($fo_file) . "'");
}
// rename fo file name to have fo extension
$realoutput = $fo_file.".fo";
$mv_result=exec("mv ".$fo_file." ".$realoutput, $output_string, $rename_res);
if($this->debug_pdf){ error_log("Result of the renaming of the FO file: '" . $rename_res . "'"); }
$fo_file = $realoutput;
if($this->debug_pdf){ error_log("Renamed file exists: '" . is_file($fo_file) . "'"); }
return $fo_file;
}
function XML2XSLFOTransformation($fo_file){
libxml_use_internal_errors(true);
// Load the XML source
$xml = new DOMDocument;
$xml->loadXML($this->xml_string);
// Load the XSL source
$xsl = new DOMDocument;
$xsl->load($this->xslt_file);
// Configure the xslt processor
$proc = new XSLTProcessor;
$proc->importStyleSheet($xsl); // attach the xsl rules
// create array to hold the xslt transformation parameters
$params=array();
// assign some xslt parameters
$params["sectionid"]="HR";
// set parameters
foreach ($params as $param => $value) { $proc->setParameter("", $param, $value); }
// perform XSLT transformation to generate fo file
$xsl_transformation=$proc->transformToURI($xml, $fo_file);
if (!$xsl_transformation) {
$errors = libxml_get_errors();
foreach ($errors as $error) {
error_log("XML Error: '" . $this->display_xml_error($error). "'");
}
libxml_clear_errors();
}
return $xsl_transformation;
}
function display_xml_error($error)
{
$return = $xml[$error->line - 1] . "\n";
$return .= str_repeat('-', $error->column) . "^\n";
switch ($error->level) {
case LIBXML_ERR_WARNING:
$return .= "Warning $error->code: ";
break;
case LIBXML_ERR_ERROR:
$return .= "Error $error->code: ";
break;
case LIBXML_ERR_FATAL:
$return .= "Fatal Error $error->code: ";
break;
}
$return .= trim($error->message) .
"\n Line: $error->line" .
"\n Column: $error->column";
if ($error->file) {
$return .= "\n File: $error->file";
}
return "$return\n\n--------------------------------------------\n\n";
}
} // end of class declaration
?>
Comments
Post a Comment